ayasee 0.1.0rc2__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 (317) hide show
  1. ayasee-0.1.0rc2/.github/workflows/ci.yml +150 -0
  2. ayasee-0.1.0rc2/.github/workflows/cockpit-collect.yml +289 -0
  3. ayasee-0.1.0rc2/.github/workflows/docs.yml +54 -0
  4. ayasee-0.1.0rc2/.github/workflows/e2e.yml +94 -0
  5. ayasee-0.1.0rc2/.github/workflows/iac-breakglass.yml +427 -0
  6. ayasee-0.1.0rc2/.github/workflows/iac-nightly.yml +382 -0
  7. ayasee-0.1.0rc2/.github/workflows/iac-pr.yml +579 -0
  8. ayasee-0.1.0rc2/.github/workflows/iac-staged.yml +861 -0
  9. ayasee-0.1.0rc2/.github/workflows/release.yml +276 -0
  10. ayasee-0.1.0rc2/.gitignore +37 -0
  11. ayasee-0.1.0rc2/.impeccable/design.json +962 -0
  12. ayasee-0.1.0rc2/.python-version +1 -0
  13. ayasee-0.1.0rc2/CHANGELOG.md +214 -0
  14. ayasee-0.1.0rc2/CONTRIBUTING.md +115 -0
  15. ayasee-0.1.0rc2/DESIGN.md +401 -0
  16. ayasee-0.1.0rc2/GOVERNANCE.md +24 -0
  17. ayasee-0.1.0rc2/LICENSE +202 -0
  18. ayasee-0.1.0rc2/NOTICE +15 -0
  19. ayasee-0.1.0rc2/PKG-INFO +41 -0
  20. ayasee-0.1.0rc2/PRODUCT.md +90 -0
  21. ayasee-0.1.0rc2/README.md +26 -0
  22. ayasee-0.1.0rc2/SECURITY.md +113 -0
  23. ayasee-0.1.0rc2/actions/apply/action.yml +79 -0
  24. ayasee-0.1.0rc2/actions/apply/apply.sh +187 -0
  25. ayasee-0.1.0rc2/actions/cockpit-site/action.yml +66 -0
  26. ayasee-0.1.0rc2/actions/guard/action.yml +39 -0
  27. ayasee-0.1.0rc2/actions/ledger/action.yml +58 -0
  28. ayasee-0.1.0rc2/actions/lib/ayasee-lib.sh +328 -0
  29. ayasee-0.1.0rc2/actions/notify/action.yml +55 -0
  30. ayasee-0.1.0rc2/actions/plan/action.yml +125 -0
  31. ayasee-0.1.0rc2/actions/plan/encryption.tofu.tmpl +14 -0
  32. ayasee-0.1.0rc2/actions/plan/plan.sh +126 -0
  33. ayasee-0.1.0rc2/actions/policy/action.yml +34 -0
  34. ayasee-0.1.0rc2/actions/policy/policy.sh +38 -0
  35. ayasee-0.1.0rc2/actions/risk/action.yml +54 -0
  36. ayasee-0.1.0rc2/actions/setup/action.yml +46 -0
  37. ayasee-0.1.0rc2/actions/setup/install.sh +54 -0
  38. ayasee-0.1.0rc2/cockpit-site/.gitignore +2 -0
  39. ayasee-0.1.0rc2/cockpit-site/index.html +26 -0
  40. ayasee-0.1.0rc2/cockpit-site/package-lock.json +2030 -0
  41. ayasee-0.1.0rc2/cockpit-site/package.json +21 -0
  42. ayasee-0.1.0rc2/cockpit-site/src/app.ts +169 -0
  43. ayasee-0.1.0rc2/cockpit-site/src/drawer.ts +358 -0
  44. ayasee-0.1.0rc2/cockpit-site/src/format.ts +53 -0
  45. ayasee-0.1.0rc2/cockpit-site/src/history.ts +98 -0
  46. ayasee-0.1.0rc2/cockpit-site/src/load.ts +60 -0
  47. ayasee-0.1.0rc2/cockpit-site/src/main.ts +10 -0
  48. ayasee-0.1.0rc2/cockpit-site/src/matrix.ts +334 -0
  49. ayasee-0.1.0rc2/cockpit-site/src/model.ts +68 -0
  50. ayasee-0.1.0rc2/cockpit-site/src/status.ts +110 -0
  51. ayasee-0.1.0rc2/cockpit-site/src/styles.css +225 -0
  52. ayasee-0.1.0rc2/cockpit-site/test/drawer.test.ts +381 -0
  53. ayasee-0.1.0rc2/cockpit-site/test/fixtures/snapshot.json +257 -0
  54. ayasee-0.1.0rc2/cockpit-site/test/history.test.ts +139 -0
  55. ayasee-0.1.0rc2/cockpit-site/test/load.test.ts +100 -0
  56. ayasee-0.1.0rc2/cockpit-site/test/matrix.test.ts +203 -0
  57. ayasee-0.1.0rc2/cockpit-site/test/model.test.ts +22 -0
  58. ayasee-0.1.0rc2/cockpit-site/test/status.test.ts +62 -0
  59. ayasee-0.1.0rc2/cockpit-site/tsconfig.json +20 -0
  60. ayasee-0.1.0rc2/cockpit-site/vite.config.ts +14 -0
  61. ayasee-0.1.0rc2/docs/README.md +87 -0
  62. ayasee-0.1.0rc2/docs/cockpit/setup.md +132 -0
  63. ayasee-0.1.0rc2/docs/comparison.md +204 -0
  64. ayasee-0.1.0rc2/docs/compliance/dora-art17.md +107 -0
  65. ayasee-0.1.0rc2/docs/concepts/architecture.md +258 -0
  66. ayasee-0.1.0rc2/docs/concepts/cockpit.md +153 -0
  67. ayasee-0.1.0rc2/docs/concepts/drift.md +119 -0
  68. ayasee-0.1.0rc2/docs/concepts/ledger.md +142 -0
  69. ayasee-0.1.0rc2/docs/concepts/plan-binding.md +202 -0
  70. ayasee-0.1.0rc2/docs/concepts/pr-checks.md +187 -0
  71. ayasee-0.1.0rc2/docs/concepts/risk-gate.md +191 -0
  72. ayasee-0.1.0rc2/docs/concepts/staged-run.md +298 -0
  73. ayasee-0.1.0rc2/docs/governance/PROVENANCE.md +51 -0
  74. ayasee-0.1.0rc2/docs/governance/decisions.md +26 -0
  75. ayasee-0.1.0rc2/docs/guides/migrate-from-env-branches.md +171 -0
  76. ayasee-0.1.0rc2/docs/guides/onboard-brownfield.md +141 -0
  77. ayasee-0.1.0rc2/docs/guides/quickstart.md +304 -0
  78. ayasee-0.1.0rc2/docs/guides/releasing.md +172 -0
  79. ayasee-0.1.0rc2/docs/reference/ayasee-yaml.md +88 -0
  80. ayasee-0.1.0rc2/docs/reference/policy-pack.md +80 -0
  81. ayasee-0.1.0rc2/docs/superpowers/plans/2026-11-06-ayasee-framework.md +599 -0
  82. ayasee-0.1.0rc2/e2e/README.md +206 -0
  83. ayasee-0.1.0rc2/e2e/__init__.py +0 -0
  84. ayasee-0.1.0rc2/e2e/ephemeral.py +650 -0
  85. ayasee-0.1.0rc2/e2e/fixture/.ayasee.yaml +11 -0
  86. ayasee-0.1.0rc2/e2e/fixture/.github/workflows/breakglass.yml +36 -0
  87. ayasee-0.1.0rc2/e2e/fixture/.github/workflows/main.yml +22 -0
  88. ayasee-0.1.0rc2/e2e/fixture/.github/workflows/nightly.yml +25 -0
  89. ayasee-0.1.0rc2/e2e/fixture/.github/workflows/pr.yml +18 -0
  90. ayasee-0.1.0rc2/e2e/fixture/e2e-generation.txt +1 -0
  91. ayasee-0.1.0rc2/e2e/fixture/e2e-grants-tag.txt +1 -0
  92. ayasee-0.1.0rc2/e2e/fixture/e2e-marker.txt +1 -0
  93. ayasee-0.1.0rc2/e2e/fixture/root.hcl +34 -0
  94. ayasee-0.1.0rc2/e2e/fixture/scripts/state-sync.sh +87 -0
  95. ayasee-0.1.0rc2/e2e/fixture/stages/dev/base/main.tf +28 -0
  96. ayasee-0.1.0rc2/e2e/fixture/stages/dev/base/terragrunt.hcl +10 -0
  97. ayasee-0.1.0rc2/e2e/fixture/stages/dev/grants/main.tf +19 -0
  98. ayasee-0.1.0rc2/e2e/fixture/stages/dev/grants/terragrunt.hcl +27 -0
  99. ayasee-0.1.0rc2/e2e/fixture/stages/prod/base/main.tf +28 -0
  100. ayasee-0.1.0rc2/e2e/fixture/stages/prod/base/terragrunt.hcl +10 -0
  101. ayasee-0.1.0rc2/e2e/fixture/stages/prod/grants/main.tf +19 -0
  102. ayasee-0.1.0rc2/e2e/fixture/stages/prod/grants/terragrunt.hcl +27 -0
  103. ayasee-0.1.0rc2/e2e/fixture/stages/uat/base/main.tf +28 -0
  104. ayasee-0.1.0rc2/e2e/fixture/stages/uat/base/terragrunt.hcl +10 -0
  105. ayasee-0.1.0rc2/e2e/fixture/stages/uat/grants/main.tf +19 -0
  106. ayasee-0.1.0rc2/e2e/fixture/stages/uat/grants/terragrunt.hcl +27 -0
  107. ayasee-0.1.0rc2/e2e/ghes/README.md +91 -0
  108. ayasee-0.1.0rc2/e2e/run.py +119 -0
  109. ayasee-0.1.0rc2/e2e/sandbox.py +366 -0
  110. ayasee-0.1.0rc2/e2e/scenarios/__init__.py +16 -0
  111. ayasee-0.1.0rc2/e2e/scenarios/breakglass.py +58 -0
  112. ayasee-0.1.0rc2/e2e/scenarios/cascade.py +49 -0
  113. ayasee-0.1.0rc2/e2e/scenarios/common.py +99 -0
  114. ayasee-0.1.0rc2/e2e/scenarios/dev_apply_fail.py +37 -0
  115. ayasee-0.1.0rc2/e2e/scenarios/drift.py +26 -0
  116. ayasee-0.1.0rc2/e2e/scenarios/drift_cleared.py +40 -0
  117. ayasee-0.1.0rc2/e2e/scenarios/empty_prod.py +26 -0
  118. ayasee-0.1.0rc2/e2e/scenarios/gate_reject.py +24 -0
  119. ayasee-0.1.0rc2/e2e/scenarios/pr_plan_fail.py +22 -0
  120. ayasee-0.1.0rc2/e2e/scenarios/scan_fail.py +27 -0
  121. ayasee-0.1.0rc2/e2e/scenarios/stale_plan.py +55 -0
  122. ayasee-0.1.0rc2/e2e/scenarios/supersession.py +58 -0
  123. ayasee-0.1.0rc2/e2e/scenarios/valid.py +24 -0
  124. ayasee-0.1.0rc2/e2e/seed.sh +31 -0
  125. ayasee-0.1.0rc2/examples/databricks-azure/.ayasee.yaml +23 -0
  126. ayasee-0.1.0rc2/examples/databricks-azure/.github/workflows/breakglass.yml +35 -0
  127. ayasee-0.1.0rc2/examples/databricks-azure/.github/workflows/cockpit.yml +34 -0
  128. ayasee-0.1.0rc2/examples/databricks-azure/.github/workflows/main.yml +20 -0
  129. ayasee-0.1.0rc2/examples/databricks-azure/.github/workflows/nightly.yml +21 -0
  130. ayasee-0.1.0rc2/examples/databricks-azure/.github/workflows/pr.yml +19 -0
  131. ayasee-0.1.0rc2/examples/databricks-azure/OWNERSHIP.md +66 -0
  132. ayasee-0.1.0rc2/examples/databricks-azure/README.md +182 -0
  133. ayasee-0.1.0rc2/examples/databricks-azure/bootstrap/.terraform.lock.hcl +73 -0
  134. ayasee-0.1.0rc2/examples/databricks-azure/bootstrap/main.tf +81 -0
  135. ayasee-0.1.0rc2/examples/databricks-azure/bootstrap/outputs.tf +14 -0
  136. ayasee-0.1.0rc2/examples/databricks-azure/bootstrap/variables.tf +57 -0
  137. ayasee-0.1.0rc2/examples/databricks-azure/renovate.json +33 -0
  138. ayasee-0.1.0rc2/examples/databricks-azure/root.hcl +35 -0
  139. ayasee-0.1.0rc2/examples/databricks-azure/shared/grants/main.tf +42 -0
  140. ayasee-0.1.0rc2/examples/databricks-azure/shared/unity-catalog/main.tf +119 -0
  141. ayasee-0.1.0rc2/examples/databricks-azure/shared/workspace/main.tf +113 -0
  142. ayasee-0.1.0rc2/examples/databricks-azure/stages/dev/grants/.terraform.lock.hcl +21 -0
  143. ayasee-0.1.0rc2/examples/databricks-azure/stages/dev/grants/terragrunt.hcl +28 -0
  144. ayasee-0.1.0rc2/examples/databricks-azure/stages/dev/unity-catalog/.terraform.lock.hcl +21 -0
  145. ayasee-0.1.0rc2/examples/databricks-azure/stages/dev/unity-catalog/terragrunt.hcl +33 -0
  146. ayasee-0.1.0rc2/examples/databricks-azure/stages/dev/workspace/.terraform.lock.hcl +39 -0
  147. ayasee-0.1.0rc2/examples/databricks-azure/stages/dev/workspace/terragrunt.hcl +24 -0
  148. ayasee-0.1.0rc2/examples/databricks-azure/stages/prod/grants/.terraform.lock.hcl +21 -0
  149. ayasee-0.1.0rc2/examples/databricks-azure/stages/prod/grants/terragrunt.hcl +28 -0
  150. ayasee-0.1.0rc2/examples/databricks-azure/stages/prod/unity-catalog/.terraform.lock.hcl +21 -0
  151. ayasee-0.1.0rc2/examples/databricks-azure/stages/prod/unity-catalog/terragrunt.hcl +33 -0
  152. ayasee-0.1.0rc2/examples/databricks-azure/stages/prod/workspace/.terraform.lock.hcl +39 -0
  153. ayasee-0.1.0rc2/examples/databricks-azure/stages/prod/workspace/terragrunt.hcl +24 -0
  154. ayasee-0.1.0rc2/examples/databricks-azure/stages/uat/grants/.terraform.lock.hcl +21 -0
  155. ayasee-0.1.0rc2/examples/databricks-azure/stages/uat/grants/terragrunt.hcl +28 -0
  156. ayasee-0.1.0rc2/examples/databricks-azure/stages/uat/unity-catalog/.terraform.lock.hcl +21 -0
  157. ayasee-0.1.0rc2/examples/databricks-azure/stages/uat/unity-catalog/terragrunt.hcl +33 -0
  158. ayasee-0.1.0rc2/examples/databricks-azure/stages/uat/workspace/.terraform.lock.hcl +39 -0
  159. ayasee-0.1.0rc2/examples/databricks-azure/stages/uat/workspace/terragrunt.hcl +24 -0
  160. ayasee-0.1.0rc2/modules/azure-stage-identity/.terraform.lock.hcl +39 -0
  161. ayasee-0.1.0rc2/modules/azure-stage-identity/README.md +49 -0
  162. ayasee-0.1.0rc2/modules/azure-stage-identity/main.tf +30 -0
  163. ayasee-0.1.0rc2/modules/azure-stage-identity/outputs.tf +14 -0
  164. ayasee-0.1.0rc2/modules/azure-stage-identity/tests/subjects.tftest.hcl +123 -0
  165. ayasee-0.1.0rc2/modules/azure-stage-identity/variables.tf +42 -0
  166. ayasee-0.1.0rc2/modules/github-environments/.terraform.lock.hcl +36 -0
  167. ayasee-0.1.0rc2/modules/github-environments/README.md +34 -0
  168. ayasee-0.1.0rc2/modules/github-environments/main.tf +86 -0
  169. ayasee-0.1.0rc2/modules/github-environments/outputs.tf +4 -0
  170. ayasee-0.1.0rc2/modules/github-environments/tests/defaults.tftest.hcl +203 -0
  171. ayasee-0.1.0rc2/modules/github-environments/variables.tf +61 -0
  172. ayasee-0.1.0rc2/policy/cloudflare/edge.rego +148 -0
  173. ayasee-0.1.0rc2/policy/cloudflare/edge_test.rego +133 -0
  174. ayasee-0.1.0rc2/policy/databricks/grants.rego +47 -0
  175. ayasee-0.1.0rc2/policy/databricks/grants_test.rego +103 -0
  176. ayasee-0.1.0rc2/policy/databricks/storage.rego +39 -0
  177. ayasee-0.1.0rc2/policy/databricks/storage_test.rego +85 -0
  178. ayasee-0.1.0rc2/policy/databricks/workspace.rego +30 -0
  179. ayasee-0.1.0rc2/policy/databricks/workspace_test.rego +34 -0
  180. ayasee-0.1.0rc2/pyproject.toml +58 -0
  181. ayasee-0.1.0rc2/renovate.json +5 -0
  182. ayasee-0.1.0rc2/rules/cloudflare.yaml +94 -0
  183. ayasee-0.1.0rc2/rules/databricks-azure.yaml +85 -0
  184. ayasee-0.1.0rc2/schema/fixtures/env-order.json +13 -0
  185. ayasee-0.1.0rc2/schema/fixtures/status-precedence.json +36 -0
  186. ayasee-0.1.0rc2/schema/snapshot.v1.json +85 -0
  187. ayasee-0.1.0rc2/scripts/build-docs-site.py +132 -0
  188. ayasee-0.1.0rc2/scripts/check-links.py +237 -0
  189. ayasee-0.1.0rc2/scripts/check-policy-fixture.sh +31 -0
  190. ayasee-0.1.0rc2/scripts/check-provenance.sh +42 -0
  191. ayasee-0.1.0rc2/scripts/install-dev-tools.sh +81 -0
  192. ayasee-0.1.0rc2/scripts/pin-release.sh +40 -0
  193. ayasee-0.1.0rc2/scripts/set-ayasee-ref.sh +45 -0
  194. ayasee-0.1.0rc2/scripts/snapshot-changed.sh +20 -0
  195. ayasee-0.1.0rc2/src/ayasee/__init__.py +3 -0
  196. ayasee-0.1.0rc2/src/ayasee/approvals.py +117 -0
  197. ayasee-0.1.0rc2/src/ayasee/binding.py +335 -0
  198. ayasee-0.1.0rc2/src/ayasee/cascade.py +81 -0
  199. ayasee-0.1.0rc2/src/ayasee/changed.py +250 -0
  200. ayasee-0.1.0rc2/src/ayasee/changeset.py +215 -0
  201. ayasee-0.1.0rc2/src/ayasee/cli.py +76 -0
  202. ayasee-0.1.0rc2/src/ayasee/cockpit/__init__.py +0 -0
  203. ayasee-0.1.0rc2/src/ayasee/cockpit/collect.py +326 -0
  204. ayasee-0.1.0rc2/src/ayasee/cockpit/render_md.py +282 -0
  205. ayasee-0.1.0rc2/src/ayasee/config.py +403 -0
  206. ayasee-0.1.0rc2/src/ayasee/drift.py +253 -0
  207. ayasee-0.1.0rc2/src/ayasee/features.py +131 -0
  208. ayasee-0.1.0rc2/src/ayasee/findings.py +52 -0
  209. ayasee-0.1.0rc2/src/ayasee/github.py +590 -0
  210. ayasee-0.1.0rc2/src/ayasee/guard.py +159 -0
  211. ayasee-0.1.0rc2/src/ayasee/issues.py +179 -0
  212. ayasee-0.1.0rc2/src/ayasee/labels.py +6 -0
  213. ayasee-0.1.0rc2/src/ayasee/ledger.py +747 -0
  214. ayasee-0.1.0rc2/src/ayasee/maintip.py +43 -0
  215. ayasee-0.1.0rc2/src/ayasee/notify.py +174 -0
  216. ayasee-0.1.0rc2/src/ayasee/planjson.py +159 -0
  217. ayasee-0.1.0rc2/src/ayasee/prcomment.py +84 -0
  218. ayasee-0.1.0rc2/src/ayasee/risk.py +315 -0
  219. ayasee-0.1.0rc2/src/ayasee/sarif.py +222 -0
  220. ayasee-0.1.0rc2/tests/actions/test_action_metadata.py +66 -0
  221. ayasee-0.1.0rc2/tests/actions/test_lib_check_mode.py +28 -0
  222. ayasee-0.1.0rc2/tests/actions/test_scripts_integration.py +837 -0
  223. ayasee-0.1.0rc2/tests/actions/test_setup_install.py +95 -0
  224. ayasee-0.1.0rc2/tests/actions/test_tool_mirror.py +167 -0
  225. ayasee-0.1.0rc2/tests/cockpit/test_collect.py +606 -0
  226. ayasee-0.1.0rc2/tests/cockpit/test_render_md.py +432 -0
  227. ayasee-0.1.0rc2/tests/e2e/fake_sandbox.py +425 -0
  228. ayasee-0.1.0rc2/tests/e2e/test_assets.py +92 -0
  229. ayasee-0.1.0rc2/tests/e2e/test_ephemeral.py +386 -0
  230. ayasee-0.1.0rc2/tests/e2e/test_run.py +146 -0
  231. ayasee-0.1.0rc2/tests/e2e/test_sandbox.py +436 -0
  232. ayasee-0.1.0rc2/tests/e2e/test_scenarios.py +138 -0
  233. ayasee-0.1.0rc2/tests/e2e/test_state_sync.py +178 -0
  234. ayasee-0.1.0rc2/tests/examples/test_example_wiring.py +463 -0
  235. ayasee-0.1.0rc2/tests/fixtures/plans/bad_format_version.json +24 -0
  236. ayasee-0.1.0rc2/tests/fixtures/plans/create.json +24 -0
  237. ayasee-0.1.0rc2/tests/fixtures/plans/delete.json +24 -0
  238. ayasee-0.1.0rc2/tests/fixtures/plans/forget.json +24 -0
  239. ayasee-0.1.0rc2/tests/fixtures/plans/forget_metastore.json +24 -0
  240. ayasee-0.1.0rc2/tests/fixtures/plans/grants_sensitive.json +50 -0
  241. ayasee-0.1.0rc2/tests/fixtures/plans/grants_update.json +73 -0
  242. ayasee-0.1.0rc2/tests/fixtures/plans/import.json +29 -0
  243. ayasee-0.1.0rc2/tests/fixtures/plans/moved.json +27 -0
  244. ayasee-0.1.0rc2/tests/fixtures/plans/noop.json +26 -0
  245. ayasee-0.1.0rc2/tests/fixtures/plans/permissions_level.json +46 -0
  246. ayasee-0.1.0rc2/tests/fixtures/plans/read.json +43 -0
  247. ayasee-0.1.0rc2/tests/fixtures/plans/replace_create_delete.json +27 -0
  248. ayasee-0.1.0rc2/tests/fixtures/plans/replace_delete_create.json +27 -0
  249. ayasee-0.1.0rc2/tests/fixtures/plans/role_assignment_create.json +26 -0
  250. ayasee-0.1.0rc2/tests/fixtures/plans/sensitive.json +30 -0
  251. ayasee-0.1.0rc2/tests/fixtures/plans/unknown.json +26 -0
  252. ayasee-0.1.0rc2/tests/fixtures/plans/update.json +28 -0
  253. ayasee-0.1.0rc2/tests/fixtures/plans/workspace_replace.json +29 -0
  254. ayasee-0.1.0rc2/tests/fixtures/policy/example_prod_plan.json +151 -0
  255. ayasee-0.1.0rc2/tests/fixtures/policy/example_prod_plan_public.json +151 -0
  256. ayasee-0.1.0rc2/tests/fixtures/policy/prod.data.json +1 -0
  257. ayasee-0.1.0rc2/tests/fixtures/policy/proxy_off.json +1 -0
  258. ayasee-0.1.0rc2/tests/fixtures/policy/public_workspace.json +1 -0
  259. ayasee-0.1.0rc2/tests/fixtures/tg/stages/dev/app/main.tf +3 -0
  260. ayasee-0.1.0rc2/tests/fixtures/tg/stages/dev/app/terragrunt.hcl +14 -0
  261. ayasee-0.1.0rc2/tests/fixtures/tg/stages/dev/base/main.tf +7 -0
  262. ayasee-0.1.0rc2/tests/fixtures/tg/stages/dev/base/terragrunt.hcl +10 -0
  263. ayasee-0.1.0rc2/tests/fixtures/tg_dep/stages/dev/base/main.tf +11 -0
  264. ayasee-0.1.0rc2/tests/fixtures/tg_dep/stages/dev/base/terragrunt.hcl +14 -0
  265. ayasee-0.1.0rc2/tests/fixtures/tg_dep/stages/dev/grants/main.tf +14 -0
  266. ayasee-0.1.0rc2/tests/fixtures/tg_dep/stages/dev/grants/terragrunt.hcl +25 -0
  267. ayasee-0.1.0rc2/tests/fixtures/tg_drift/stages/dev/base/main.tf +3 -0
  268. ayasee-0.1.0rc2/tests/fixtures/tg_drift/stages/dev/base/terragrunt.hcl +10 -0
  269. ayasee-0.1.0rc2/tests/fixtures/tg_drift/stages/dev/drift/main.tf +4 -0
  270. ayasee-0.1.0rc2/tests/fixtures/tg_drift/stages/dev/drift/terragrunt.hcl +14 -0
  271. ayasee-0.1.0rc2/tests/fixtures/tg_drift/stages/dev/last/main.tf +3 -0
  272. ayasee-0.1.0rc2/tests/fixtures/tg_drift/stages/dev/last/terragrunt.hcl +14 -0
  273. ayasee-0.1.0rc2/tests/fixtures/tg_fail/stages/dev/bad/main.tf +7 -0
  274. ayasee-0.1.0rc2/tests/fixtures/tg_fail/stages/dev/bad/terragrunt.hcl +14 -0
  275. ayasee-0.1.0rc2/tests/fixtures/tg_fail/stages/dev/base/main.tf +3 -0
  276. ayasee-0.1.0rc2/tests/fixtures/tg_fail/stages/dev/base/terragrunt.hcl +10 -0
  277. ayasee-0.1.0rc2/tests/fixtures/tg_fail/stages/dev/last/main.tf +3 -0
  278. ayasee-0.1.0rc2/tests/fixtures/tg_fail/stages/dev/last/terragrunt.hcl +14 -0
  279. ayasee-0.1.0rc2/tests/test_approvals_issues.py +378 -0
  280. ayasee-0.1.0rc2/tests/test_binding.py +406 -0
  281. ayasee-0.1.0rc2/tests/test_cascade.py +79 -0
  282. ayasee-0.1.0rc2/tests/test_changed.py +273 -0
  283. ayasee-0.1.0rc2/tests/test_changeset.py +320 -0
  284. ayasee-0.1.0rc2/tests/test_check_links.py +165 -0
  285. ayasee-0.1.0rc2/tests/test_check_provenance.py +94 -0
  286. ayasee-0.1.0rc2/tests/test_cli.py +26 -0
  287. ayasee-0.1.0rc2/tests/test_config.py +434 -0
  288. ayasee-0.1.0rc2/tests/test_drift.py +357 -0
  289. ayasee-0.1.0rc2/tests/test_features.py +167 -0
  290. ayasee-0.1.0rc2/tests/test_findings.py +110 -0
  291. ayasee-0.1.0rc2/tests/test_github.py +413 -0
  292. ayasee-0.1.0rc2/tests/test_guard.py +360 -0
  293. ayasee-0.1.0rc2/tests/test_ledger.py +766 -0
  294. ayasee-0.1.0rc2/tests/test_maintip.py +49 -0
  295. ayasee-0.1.0rc2/tests/test_notify.py +179 -0
  296. ayasee-0.1.0rc2/tests/test_planjson.py +215 -0
  297. ayasee-0.1.0rc2/tests/test_prcomment.py +163 -0
  298. ayasee-0.1.0rc2/tests/test_risk.py +177 -0
  299. ayasee-0.1.0rc2/tests/test_risk_cloudflare.py +180 -0
  300. ayasee-0.1.0rc2/tests/test_sarif.py +298 -0
  301. ayasee-0.1.0rc2/tests/workflows/conftest.py +17 -0
  302. ayasee-0.1.0rc2/tests/workflows/test_breakglass.py +376 -0
  303. ayasee-0.1.0rc2/tests/workflows/test_cockpit_collect.py +428 -0
  304. ayasee-0.1.0rc2/tests/workflows/test_iac_nightly.py +295 -0
  305. ayasee-0.1.0rc2/tests/workflows/test_iac_pr.py +486 -0
  306. ayasee-0.1.0rc2/tests/workflows/test_iac_staged.py +641 -0
  307. ayasee-0.1.0rc2/tests/workflows/test_identity_profile.py +158 -0
  308. ayasee-0.1.0rc2/tests/workflows/test_release.py +263 -0
  309. ayasee-0.1.0rc2/uv.lock +1205 -0
  310. ayasee-0.1.0rc2/website/index.md +220 -0
  311. ayasee-0.1.0rc2/website/javascripts/tables.js +43 -0
  312. ayasee-0.1.0rc2/website/javascripts/vendor/mermaid-11.17.2.LICENSE.txt +21 -0
  313. ayasee-0.1.0rc2/website/javascripts/vendor/mermaid-11.17.2.min.js +3636 -0
  314. ayasee-0.1.0rc2/website/mkdocs.yml +140 -0
  315. ayasee-0.1.0rc2/website/overrides/main.html +13 -0
  316. ayasee-0.1.0rc2/website/overrides/partials/source.html +14 -0
  317. ayasee-0.1.0rc2/website/stylesheets/extra.css +450 -0
@@ -0,0 +1,150 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions: {}
9
+
10
+ # Jobs are added by the tasks that introduce their inputs.
11
+ jobs:
12
+ ruff:
13
+ name: ruff
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ contents: read
17
+ steps:
18
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
19
+ with:
20
+ persist-credentials: false
21
+ - uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
22
+ with:
23
+ enable-cache: false
24
+ - run: uv run ruff check
25
+
26
+ pytest:
27
+ name: pytest
28
+ runs-on: ubuntu-latest
29
+ permissions:
30
+ contents: read
31
+ steps:
32
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
33
+ with:
34
+ persist-credentials: false
35
+ - uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
36
+ with:
37
+ enable-cache: false
38
+ - run: uv run pytest -m "not integration"
39
+
40
+ integration:
41
+ name: integration
42
+ runs-on: ubuntu-latest
43
+ permissions:
44
+ contents: read
45
+ steps:
46
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
47
+ with:
48
+ persist-credentials: false
49
+ - uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
50
+ with:
51
+ enable-cache: false
52
+ - uses: opentofu/setup-opentofu@a1320f892987e89d278cc92dc5adc984fb93aca4 # v2.0.2
53
+ with:
54
+ tofu_version: 1.13.9
55
+ tofu_wrapper: false
56
+ - run: scripts/install-dev-tools.sh terragrunt
57
+ - run: uv run pytest -m integration
58
+
59
+ tofu-test:
60
+ name: tofu test
61
+ runs-on: ubuntu-latest
62
+ permissions:
63
+ contents: read
64
+ steps:
65
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
66
+ with:
67
+ persist-credentials: false
68
+ - uses: opentofu/setup-opentofu@a1320f892987e89d278cc92dc5adc984fb93aca4 # v2.0.2
69
+ with:
70
+ tofu_version: 1.12.6
71
+ tofu_wrapper: false
72
+ - run: tofu fmt -check -recursive modules/
73
+ - name: tofu test each module
74
+ run: |
75
+ for m in modules/*/; do
76
+ (cd "$m" && tofu init -backend=false && tofu validate && tofu test)
77
+ done
78
+
79
+ cockpit-site:
80
+ name: cockpit-site
81
+ runs-on: ubuntu-latest
82
+ permissions:
83
+ contents: read
84
+ defaults:
85
+ run:
86
+ working-directory: cockpit-site
87
+ steps:
88
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
89
+ with:
90
+ persist-credentials: false
91
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
92
+ with:
93
+ node-version: 22
94
+ package-manager-cache: false
95
+ - run: npm ci --ignore-scripts --no-audit --no-fund
96
+ - run: npm run typecheck
97
+ - run: npm test
98
+ - run: npm run build
99
+
100
+ actionlint:
101
+ name: actionlint
102
+ runs-on: ubuntu-latest
103
+ permissions:
104
+ contents: read
105
+ steps:
106
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
107
+ with:
108
+ persist-credentials: false
109
+ - run: scripts/install-dev-tools.sh actionlint
110
+ - run: .tools/bin/actionlint
111
+
112
+ opa:
113
+ name: opa test
114
+ runs-on: ubuntu-latest
115
+ permissions:
116
+ contents: read
117
+ steps:
118
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
119
+ with:
120
+ persist-credentials: false
121
+ - run: scripts/install-dev-tools.sh opa conftest
122
+ - run: .tools/bin/opa check --strict policy/
123
+ - run: .tools/bin/opa fmt --fail policy/
124
+ - run: .tools/bin/opa test policy/ -v
125
+ - run: scripts/check-policy-fixture.sh
126
+
127
+ links:
128
+ name: doc links
129
+ runs-on: ubuntu-latest
130
+ permissions:
131
+ contents: read
132
+ steps:
133
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
134
+ with:
135
+ persist-credentials: false
136
+ - run: python3 scripts/check-links.py
137
+
138
+ zizmor:
139
+ name: zizmor
140
+ runs-on: ubuntu-latest
141
+ permissions:
142
+ contents: read
143
+ steps:
144
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
145
+ with:
146
+ persist-credentials: false
147
+ - uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
148
+ with:
149
+ enable-cache: false
150
+ - run: uvx zizmor@1.32.0 --offline .github/ actions/
@@ -0,0 +1,289 @@
1
+ # Cockpit collector: runs `ayasee cockpit collect` across the estate, commits snapshot.json and a
2
+ # dated history copy to the data repository, then renders it (pages | issue | summary).
3
+ # Callers add their own `workflow_run` (iac-staged and iac-nightly completed) and `schedule`
4
+ # (*/30 * * * *) triggers: see docs/cockpit/setup.md for a wrapper. Do not set a concurrency group
5
+ # named ayasee-cockpit in the wrapper: it would collide with the group below. The group allows
6
+ # one run at a time; while one runs, a newer pending run replaces an older pending one (the older
7
+ # is cancelled), so at most one run waits. The group is per repository: use one wrapper
8
+ # repository per data repository, or two wrappers would push to the data repository concurrently.
9
+ #
10
+ # Lines marked AYASEE_REF, AYASEE_REPO and AYASEE_SHA are placeholders (all-zero SHA, owner
11
+ # OWNER): scripts/set-ayasee-ref.sh rewrites them at release. This file is not callable before
12
+ # that. The collect job checks out the ayasee source at the same pinned commit into
13
+ # ayasee-src/ for scripts/ (R33: a reusable workflow cannot rely on github.job_workflow_sha);
14
+ # the pages job builds cockpit-site/ through the pinned cockpit-site action. The `--local`
15
+ # (./actions) form is not supported for this workflow: no job checks out the repository root, so
16
+ # ./actions would not exist.
17
+ #
18
+ # Ledgers: the collector reads only github-branch:// ledger URLs, through the read token (it has
19
+ # no cloud login). `ayasee cockpit repos` refuses any other store URL before a token is minted.
20
+ name: cockpit-collect
21
+
22
+ on:
23
+ workflow_call:
24
+ inputs:
25
+ tool-mirror:
26
+ description: >-
27
+ Optional https base URL (no trailing slash) replacing https://github.com for tool
28
+ downloads (GitHub Enterprise Server or offline runners). SHA-256 checks still apply.
29
+ type: string
30
+ required: false
31
+ default: ""
32
+ renderer:
33
+ description: How to present the snapshot (pages, issue or summary).
34
+ type: string
35
+ required: false
36
+ default: pages
37
+ repos-file:
38
+ description: Path of the repos file inside the data repository.
39
+ type: string
40
+ required: false
41
+ default: repos.yaml
42
+ data-repository:
43
+ description: The cockpit data repository, as owner/name. Also the owner of the estate installation.
44
+ type: string
45
+ required: true
46
+ issue-number:
47
+ description: Issue of the data repository that the issue renderer updates.
48
+ type: string
49
+ required: false
50
+ default: ""
51
+ history-days:
52
+ description: Days of history the site shows (integer, 1 to 365). Pages renderer only.
53
+ type: string
54
+ required: false
55
+ default: "30"
56
+ secrets:
57
+ app-id:
58
+ description: ID of the GitHub App (see docs/cockpit/setup.md).
59
+ required: true
60
+ app-private-key:
61
+ description: Private key of the GitHub App.
62
+ required: true
63
+
64
+ permissions: {}
65
+
66
+ concurrency:
67
+ group: ayasee-cockpit
68
+ cancel-in-progress: false
69
+
70
+ jobs:
71
+ collect:
72
+ name: collect
73
+ runs-on: ubuntu-latest
74
+ permissions:
75
+ contents: read # the App tokens carry the real access
76
+ timeout-minutes: 30
77
+ env:
78
+ SNAPSHOT_CACHE: .ayasee/etag-cache.json
79
+ steps:
80
+ - id: inputs
81
+ name: Validate the inputs
82
+ env:
83
+ RENDERER: ${{ inputs.renderer }}
84
+ DATA_REPOSITORY: ${{ inputs.data-repository }}
85
+ REPOS_FILE: ${{ inputs.repos-file }}
86
+ ISSUE_NUMBER: ${{ inputs.issue-number }}
87
+ HISTORY_DAYS: ${{ inputs.history-days }}
88
+ run: |
89
+ case "$RENDERER" in pages|issue|summary) ;; *)
90
+ echo "::error::renderer must be pages, issue or summary"
91
+ exit 1 ;;
92
+ esac
93
+ [[ "$DATA_REPOSITORY" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*/[A-Za-z0-9][A-Za-z0-9._-]*$ ]] || {
94
+ echo "::error::data-repository must be owner/name"
95
+ exit 1
96
+ }
97
+ case "$REPOS_FILE" in /*|*..*|"") echo "::error::repos-file must be a relative path inside the data repository"; exit 1 ;; esac
98
+ if ! { [[ "$HISTORY_DAYS" =~ ^[1-9][0-9]{0,2}$ ]] && [ "$HISTORY_DAYS" -le 365 ]; }; then
99
+ echo "::error::history-days must be an integer between 1 and 365"
100
+ exit 1
101
+ fi
102
+ if [ "$RENDERER" = issue ]; then
103
+ [[ "$ISSUE_NUMBER" =~ ^[1-9][0-9]*$ ]] || {
104
+ echo "::error::the issue renderer needs issue-number (a positive integer)"
105
+ exit 1
106
+ }
107
+ fi
108
+ {
109
+ echo "owner=${DATA_REPOSITORY%%/*}"
110
+ echo "name=${DATA_REPOSITORY#*/}"
111
+ } >>"$GITHUB_OUTPUT"
112
+ - id: write-token
113
+ name: Write token for the data repository only (contents)
114
+ uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
115
+ with:
116
+ app-id: ${{ secrets.app-id }}
117
+ private-key: ${{ secrets.app-private-key }}
118
+ owner: ${{ steps.inputs.outputs.owner }}
119
+ repositories: ${{ steps.inputs.outputs.name }}
120
+ permission-contents: write
121
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
122
+ with:
123
+ repository: ${{ inputs.data-repository }}
124
+ token: ${{ steps.write-token.outputs.token }}
125
+ path: data
126
+ persist-credentials: false
127
+ - name: Check out the ayasee source (scripts/)
128
+ uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
129
+ with:
130
+ repository: OWNER/ayasee # AYASEE_REPO
131
+ ref: 0000000000000000000000000000000000000000 # AYASEE_SHA
132
+ path: ayasee-src
133
+ persist-credentials: false
134
+ - uses: OWNER/ayasee/actions/setup@0000000000000000000000000000000000000000 # AYASEE_REF
135
+ with:
136
+ tool-mirror: ${{ inputs.tool-mirror }}
137
+ - id: repos
138
+ name: List the repositories of the estate
139
+ env:
140
+ REPOS_FILE: ${{ inputs.repos-file }}
141
+ OWNER: ${{ steps.inputs.outputs.owner }}
142
+ run: |
143
+ # fails when a repository belongs to another owner or there are more than 500
144
+ list="$(ayasee cockpit repos --repos-file "data/$REPOS_FILE" --owner "$OWNER")"
145
+ echo "list=$list" >>"$GITHUB_OUTPUT"
146
+ - id: read-token
147
+ name: Read token for the listed repositories only
148
+ uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
149
+ with:
150
+ app-id: ${{ secrets.app-id }}
151
+ private-key: ${{ secrets.app-private-key }}
152
+ owner: ${{ steps.inputs.outputs.owner }}
153
+ repositories: ${{ steps.repos.outputs.list }}
154
+ permission-metadata: read
155
+ permission-actions: read
156
+ permission-issues: read
157
+ permission-contents: read
158
+ permission-deployments: read
159
+ permission-security-events: read
160
+ - id: issue-token
161
+ name: Issue token (issues write on the data repository, nothing else)
162
+ if: ${{ inputs.renderer == 'issue' }}
163
+ uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
164
+ with:
165
+ app-id: ${{ secrets.app-id }}
166
+ private-key: ${{ secrets.app-private-key }}
167
+ owner: ${{ steps.inputs.outputs.owner }}
168
+ repositories: ${{ steps.inputs.outputs.name }}
169
+ permission-issues: write
170
+ - id: etag
171
+ name: Restore the ETag cache
172
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
173
+ with:
174
+ path: ${{ env.SNAPSHOT_CACHE }}
175
+ # Never an exact hit: the newest entry under restore-keys is restored. The prefix is
176
+ # scoped to the data repository; Actions caches are scoped by ref, so a cache saved from a
177
+ # PR ref is never visible to the default-branch collector.
178
+ key: ayasee-cockpit-etag-${{ inputs.data-repository }}-${{ github.run_id }}
179
+ restore-keys: ayasee-cockpit-etag-${{ inputs.data-repository }}-
180
+ - name: Collect the snapshot
181
+ env:
182
+ GITHUB_TOKEN: ${{ steps.read-token.outputs.token }}
183
+ REPOS_FILE: ${{ inputs.repos-file }}
184
+ run: |
185
+ # exit 1 means every repository failed: the job fails and nothing is committed
186
+ ayasee cockpit collect \
187
+ --repos-file "data/$REPOS_FILE" \
188
+ --etag-cache "$SNAPSHOT_CACHE" \
189
+ --out snapshot.json
190
+ - id: diff
191
+ name: Compare with the committed snapshot
192
+ run: |
193
+ # assigned first so a failing script fails the step (not swallowed by echo "$(...)")
194
+ result="$(ayasee-src/scripts/snapshot-changed.sh data/snapshot.json snapshot.json)"
195
+ echo "result=$result" >>"$GITHUB_OUTPUT"
196
+ - name: Write snapshot.json and the history copy
197
+ if: ${{ steps.diff.outputs.result == 'changed' }}
198
+ run: |
199
+ cp snapshot.json data/snapshot.json
200
+ hist="data/history/$(date -u +%Y/%m/%d)"
201
+ mkdir -p "$hist"
202
+ cp snapshot.json "$hist/$(date -u +%H%M).json"
203
+ - name: Commit and push
204
+ if: ${{ steps.diff.outputs.result == 'changed' }}
205
+ env:
206
+ WRITE_TOKEN: ${{ steps.write-token.outputs.token }}
207
+ GIT_CONFIG_COUNT: "1"
208
+ GIT_CONFIG_KEY_0: credential.${{ github.server_url }}.helper
209
+ GIT_CONFIG_VALUE_0: '!f() { echo username=x-access-token; echo "password=$WRITE_TOKEN"; }; f'
210
+ run: |
211
+ git -C data config user.name "ayasee-cockpit[bot]"
212
+ git -C data config user.email "ayasee-cockpit[bot]@users.noreply.github.com"
213
+ git -C data add snapshot.json history
214
+ git -C data commit -m "cockpit: snapshot $(date -u +%Y-%m-%dT%H:%MZ)"
215
+ git -C data push
216
+ - name: Save the ETag cache (only when its content changed)
217
+ # No status function in the condition: GitHub adds success(), so this never runs after a
218
+ # failed collect, diff or push. The key carries the content hash: an unchanged cache
219
+ # matches the restored key and is not saved again.
220
+ if: ${{ hashFiles(env.SNAPSHOT_CACHE) != '' && steps.etag.outputs.cache-matched-key != format('ayasee-cockpit-etag-{0}-{1}', inputs.data-repository, hashFiles(env.SNAPSHOT_CACHE)) }}
221
+ uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
222
+ with:
223
+ path: ${{ env.SNAPSHOT_CACHE }}
224
+ key: ayasee-cockpit-etag-${{ inputs.data-repository }}-${{ hashFiles(env.SNAPSHOT_CACHE) }}
225
+ - name: Render to the job summary
226
+ if: ${{ inputs.renderer == 'summary' }}
227
+ run: ayasee cockpit render-md --snapshot snapshot.json --summary "$GITHUB_STEP_SUMMARY"
228
+ - name: Render to an issue of the data repository
229
+ if: ${{ inputs.renderer == 'issue' }}
230
+ env:
231
+ GITHUB_TOKEN: ${{ steps.issue-token.outputs.token }}
232
+ ISSUE_NUMBER: ${{ inputs.issue-number }}
233
+ DATA_REPOSITORY: ${{ inputs.data-repository }}
234
+ run: |
235
+ ayasee cockpit render-md --snapshot snapshot.json \
236
+ --issue-number "$ISSUE_NUMBER" --repo "$DATA_REPOSITORY"
237
+ - name: Build the history index (generated for Pages only, never committed)
238
+ if: ${{ inputs.renderer == 'pages' }}
239
+ env:
240
+ HISTORY_DAYS: ${{ inputs.history-days }}
241
+ run: |
242
+ mkdir -p data/history
243
+ ayasee cockpit history-index --dir data/history --days "$HISTORY_DAYS" \
244
+ --out data/history/index.json
245
+ - name: Stage the data for the site (the fresh snapshot, not the committed one)
246
+ if: ${{ inputs.renderer == 'pages' }}
247
+ # data/snapshot.json only changes when the estate does, so its generated_at would make the
248
+ # site's stale banner fire on a quiet estate; the site gets this run's snapshot.json.
249
+ run: |
250
+ mkdir site-data
251
+ cp snapshot.json site-data/snapshot.json
252
+ cp -R data/history site-data/history
253
+ - name: Upload the data for the site
254
+ if: ${{ inputs.renderer == 'pages' }}
255
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
256
+ with:
257
+ name: cockpit-data
258
+ path: site-data
259
+ if-no-files-found: error
260
+ retention-days: 1
261
+
262
+ pages:
263
+ name: pages
264
+ needs: collect
265
+ if: ${{ inputs.renderer == 'pages' }}
266
+ runs-on: ubuntu-latest
267
+ permissions:
268
+ pages: write # deploy-pages
269
+ id-token: write # deploy-pages proves the deployment origin
270
+ environment:
271
+ name: github-pages
272
+ url: ${{ steps.deploy.outputs.page_url }}
273
+ steps:
274
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
275
+ with:
276
+ name: cockpit-data
277
+ path: cockpit-data
278
+ # builds the site and puts snapshot.json and history/ (with index.json) at the site root,
279
+ # where the page fetches ./snapshot.json and ./history/index.json
280
+ - uses: OWNER/ayasee/actions/cockpit-site@0000000000000000000000000000000000000000 # AYASEE_REF
281
+ with:
282
+ snapshot: cockpit-data/snapshot.json
283
+ history-dir: cockpit-data/history
284
+ out: site
285
+ - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
286
+ with:
287
+ path: site
288
+ - id: deploy
289
+ uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
@@ -0,0 +1,54 @@
1
+ name: docs
2
+
3
+ # Documentation site on GitHub Pages. The site is assembled from the repository's Markdown by
4
+ # scripts/build-docs-site.py and built with mkdocs in strict mode (a broken link or anchor fails
5
+ # the build). Pull requests build only; a push to main also deploys.
6
+
7
+ on:
8
+ push:
9
+ branches: [main]
10
+ pull_request:
11
+ workflow_dispatch:
12
+
13
+ permissions: {}
14
+
15
+ concurrency:
16
+ group: docs-${{ github.ref }}
17
+ cancel-in-progress: false
18
+
19
+ jobs:
20
+ build:
21
+ name: build
22
+ runs-on: ubuntu-latest
23
+ permissions:
24
+ contents: read
25
+ steps:
26
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
27
+ with:
28
+ persist-credentials: false
29
+ - uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
30
+ with:
31
+ enable-cache: false
32
+ - run: uv run --locked --only-group docs python scripts/build-docs-site.py
33
+ - run: uv run --locked --only-group docs mkdocs build --strict -f website/mkdocs.yml
34
+ env:
35
+ NO_MKDOCS_2_WARNING: "1"
36
+ - if: github.event_name != 'pull_request'
37
+ uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
38
+ with:
39
+ path: build/site
40
+
41
+ deploy:
42
+ name: deploy
43
+ if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
44
+ needs: build
45
+ runs-on: ubuntu-latest
46
+ permissions:
47
+ pages: write
48
+ id-token: write
49
+ environment:
50
+ name: github-pages
51
+ url: ${{ steps.deployment.outputs.page_url }}
52
+ steps:
53
+ - id: deployment
54
+ uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
@@ -0,0 +1,94 @@
1
+ # End-to-end scenarios against a sandbox repository (never this repository). See e2e/README.md.
2
+ # Manual or nightly, canonical repository only. Nothing here touches production.
3
+ #
4
+ # Environment `e2e` holds: secrets E2E_TOKEN (maintainer identity), E2E_APPROVER_APP_ID and
5
+ # E2E_APPROVER_APP_KEY (the second identity, a GitHub App installed on the sandbox repository),
6
+ # E2E_WEBHOOK_URL (webhook echo); variable E2E_REPO (owner/name, name ends in -sandbox).
7
+ # OWNER is a placeholder replaced at release.
8
+ name: e2e
9
+
10
+ on:
11
+ workflow_dispatch:
12
+ inputs:
13
+ scenario:
14
+ description: One scenario, or all of them.
15
+ type: choice
16
+ default: all
17
+ options:
18
+ - all
19
+ - valid
20
+ - scan_fail
21
+ - pr_plan_fail
22
+ - dev_apply_fail
23
+ - gate_reject
24
+ - drift
25
+ - drift_cleared
26
+ - supersession
27
+ - stale_plan
28
+ - empty_prod
29
+ - breakglass
30
+ schedule:
31
+ - cron: "43 3 * * *"
32
+
33
+ permissions: {}
34
+
35
+ concurrency:
36
+ group: e2e
37
+ cancel-in-progress: false
38
+
39
+ jobs:
40
+ e2e:
41
+ name: e2e
42
+ if: ${{ github.repository == 'OWNER/ayasee' }}
43
+ runs-on: ubuntu-latest
44
+ environment: e2e
45
+ timeout-minutes: 300
46
+ permissions:
47
+ contents: read
48
+ env:
49
+ UV_NO_CACHE: "1"
50
+ steps:
51
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
52
+ with:
53
+ persist-credentials: false
54
+ - uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
55
+ with:
56
+ enable-cache: false
57
+ - name: Install the pinned dependencies (before any token exists)
58
+ run: uv sync --frozen
59
+ - id: target
60
+ name: Split the sandbox repository name
61
+ env:
62
+ E2E_REPO: ${{ vars.E2E_REPO }}
63
+ run: |
64
+ case "$E2E_REPO" in
65
+ */*-sandbox) ;;
66
+ *) echo "::error::vars.E2E_REPO must be owner/<name>-sandbox"; exit 1 ;;
67
+ esac
68
+ {
69
+ echo "owner=${E2E_REPO%%/*}"
70
+ echo "name=${E2E_REPO#*/}"
71
+ } >>"$GITHUB_OUTPUT"
72
+ - id: approver
73
+ name: Token of the second identity
74
+ uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
75
+ with:
76
+ app-id: ${{ secrets.E2E_APPROVER_APP_ID }}
77
+ private-key: ${{ secrets.E2E_APPROVER_APP_KEY }}
78
+ owner: ${{ steps.target.outputs.owner }}
79
+ repositories: ${{ steps.target.outputs.name }}
80
+ permission-actions: read # run and pending-deployment state
81
+ permission-deployments: write # approve or reject environment gates
82
+ - name: Run the scenarios
83
+ env:
84
+ E2E_REPO: ${{ vars.E2E_REPO }}
85
+ E2E_TOKEN: ${{ secrets.E2E_TOKEN }}
86
+ E2E_APPROVER_TOKEN: ${{ steps.approver.outputs.token }}
87
+ E2E_WEBHOOK_URL: ${{ secrets.E2E_WEBHOOK_URL }}
88
+ SCENARIO: ${{ inputs.scenario }}
89
+ run: |
90
+ if [ -z "$SCENARIO" ] || [ "$SCENARIO" = all ]; then
91
+ uv run python -m e2e.run --all
92
+ else
93
+ uv run python -m e2e.run --scenario "$SCENARIO"
94
+ fi