ansible-aom 0.102.13__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.
- ansible_aom-0.102.13/.agent/hooks/graphify-refresh.sh +84 -0
- ansible_aom-0.102.13/.agent/hooks/pre-commit-wrapper.sh +5 -0
- ansible_aom-0.102.13/.ansible-lint +24 -0
- ansible_aom-0.102.13/.claude/settings.json +37 -0
- ansible_aom-0.102.13/.claude/skills/verify/SKILL.md +63 -0
- ansible_aom-0.102.13/.envrc +1 -0
- ansible_aom-0.102.13/.githooks/post-commit +21 -0
- ansible_aom-0.102.13/.githooks/post-commit-graphify +93 -0
- ansible_aom-0.102.13/.githooks/pre-commit +7 -0
- ansible_aom-0.102.13/.githooks/pre-push +87 -0
- ansible_aom-0.102.13/.github/dependabot.yml +16 -0
- ansible_aom-0.102.13/.github/workflows/ci.yml +80 -0
- ansible_aom-0.102.13/.github/workflows/release.yml +135 -0
- ansible_aom-0.102.13/.gitignore +64 -0
- ansible_aom-0.102.13/.gitmodules +3 -0
- ansible_aom-0.102.13/.pre-commit-config.yaml +76 -0
- ansible_aom-0.102.13/.python-version +1 -0
- ansible_aom-0.102.13/AGENTS.md +133 -0
- ansible_aom-0.102.13/ARCHITECTURE.md +567 -0
- ansible_aom-0.102.13/CHANGELOG.md +17 -0
- ansible_aom-0.102.13/CODE_OF_CONDUCT.md +9 -0
- ansible_aom-0.102.13/CONTRIBUTING.md +22 -0
- ansible_aom-0.102.13/LICENSE +674 -0
- ansible_aom-0.102.13/PKG-INFO +38 -0
- ansible_aom-0.102.13/README.md +325 -0
- ansible_aom-0.102.13/SECURITY.md +16 -0
- ansible_aom-0.102.13/SPECIFICATION.md +3208 -0
- ansible_aom-0.102.13/SUPPORT.md +12 -0
- ansible_aom-0.102.13/TEST_PLAYBOOKS.md +1264 -0
- ansible_aom-0.102.13/TEST_SPECIFICATION.md +5077 -0
- ansible_aom-0.102.13/docs/brainstorms/2026-06-29-verbosity-handling.md +1180 -0
- ansible_aom-0.102.13/docs/brainstorms/2026-06-30-qc-review-triage.md +404 -0
- ansible_aom-0.102.13/docs/brainstorms/2026-06-30-verbosity-pre-impl-interview.md +356 -0
- ansible_aom-0.102.13/docs/superpowers/specs/2026-05-19-free-strategy-tree-view-design.md +362 -0
- ansible_aom-0.102.13/docs/superpowers/specs/2026-05-19-liveness-indicator-design.md +260 -0
- ansible_aom-0.102.13/docs/superpowers/specs/2026-05-20-inspect-rebuild-design.md +370 -0
- ansible_aom-0.102.13/docs/superpowers/specs/2026-05-21-diagnostics-layer-design.md +223 -0
- ansible_aom-0.102.13/docs/superpowers/specs/2026-05-21-render-state-perf-design.md +249 -0
- ansible_aom-0.102.13/docs/superpowers/specs/2026-06-02-live-loop-item-streaming-design.md +251 -0
- ansible_aom-0.102.13/docs/superpowers/specs/2026-06-16-run-duration-estimate-design.md +240 -0
- ansible_aom-0.102.13/docs/superpowers/specs/2026-07-21-worktree-safe-version-hook-design.md +50 -0
- ansible_aom-0.102.13/flake.lock +61 -0
- ansible_aom-0.102.13/flake.nix +103 -0
- ansible_aom-0.102.13/packaging/aom.spec +47 -0
- ansible_aom-0.102.13/pyproject.toml +222 -0
- ansible_aom-0.102.13/schemas/README.md +11 -0
- ansible_aom-0.102.13/schemas/run_summary.v1.json +109 -0
- ansible_aom-0.102.13/scripts/bump_version.py +256 -0
- ansible_aom-0.102.13/scripts/check_version_bump.py +289 -0
- ansible_aom-0.102.13/scripts/check_version_consistency.py +63 -0
- ansible_aom-0.102.13/scripts/install-hooks.sh +43 -0
- ansible_aom-0.102.13/scripts/verify_anchors.py +227 -0
- ansible_aom-0.102.13/src/ansible_aom/__init__.py +74 -0
- ansible_aom-0.102.13/src/ansible_aom/__main__.py +8 -0
- ansible_aom-0.102.13/src/ansible_aom/ansible/__init__.py +6 -0
- ansible_aom-0.102.13/src/ansible_aom/ansible/callback/aom_jsonl.py +227 -0
- ansible_aom-0.102.13/src/ansible_aom/ansible/preflight.py +222 -0
- ansible_aom-0.102.13/src/ansible_aom/ansible/runner.py +1223 -0
- ansible_aom-0.102.13/src/ansible_aom/callbacks/__init__.py +6 -0
- ansible_aom-0.102.13/src/ansible_aom/callbacks/aom_connection.py +122 -0
- ansible_aom-0.102.13/src/ansible_aom/cli.py +674 -0
- ansible_aom-0.102.13/src/ansible_aom/compact/__init__.py +1 -0
- ansible_aom-0.102.13/src/ansible_aom/compact/display.py +493 -0
- ansible_aom-0.102.13/src/ansible_aom/compact/exit_code.py +12 -0
- ansible_aom-0.102.13/src/ansible_aom/compact/format.py +947 -0
- ansible_aom-0.102.13/src/ansible_aom/compact/password.py +52 -0
- ansible_aom-0.102.13/src/ansible_aom/compact/renderer.py +2174 -0
- ansible_aom-0.102.13/src/ansible_aom/completion.py +109 -0
- ansible_aom-0.102.13/src/ansible_aom/core/__init__.py +7 -0
- ansible_aom-0.102.13/src/ansible_aom/core/_async_poll.py +20 -0
- ansible_aom-0.102.13/src/ansible_aom/core/config.py +131 -0
- ansible_aom-0.102.13/src/ansible_aom/core/config_layer.py +167 -0
- ansible_aom-0.102.13/src/ansible_aom/core/default_config.yaml +33 -0
- ansible_aom-0.102.13/src/ansible_aom/core/diagnostics.py +564 -0
- ansible_aom-0.102.13/src/ansible_aom/core/duration.py +95 -0
- ansible_aom-0.102.13/src/ansible_aom/core/estimate.py +186 -0
- ansible_aom-0.102.13/src/ansible_aom/core/event_types.py +146 -0
- ansible_aom-0.102.13/src/ansible_aom/core/exit_code.py +48 -0
- ansible_aom-0.102.13/src/ansible_aom/core/heartbeat.py +115 -0
- ansible_aom-0.102.13/src/ansible_aom/core/icons.py +200 -0
- ansible_aom-0.102.13/src/ansible_aom/core/includes.py +1295 -0
- ansible_aom-0.102.13/src/ansible_aom/core/inspect_model.py +1554 -0
- ansible_aom-0.102.13/src/ansible_aom/core/log_filter.py +122 -0
- ansible_aom-0.102.13/src/ansible_aom/core/models.py +404 -0
- ansible_aom-0.102.13/src/ansible_aom/core/overhead.py +180 -0
- ansible_aom-0.102.13/src/ansible_aom/core/parity.py +112 -0
- ansible_aom-0.102.13/src/ansible_aom/core/parser.py +827 -0
- ansible_aom-0.102.13/src/ansible_aom/core/prompts.py +201 -0
- ansible_aom-0.102.13/src/ansible_aom/core/redaction.py +310 -0
- ansible_aom-0.102.13/src/ansible_aom/core/replay.py +43 -0
- ansible_aom-0.102.13/src/ansible_aom/core/run_config.py +201 -0
- ansible_aom-0.102.13/src/ansible_aom/core/run_state.py +1813 -0
- ansible_aom-0.102.13/src/ansible_aom/core/state_machine.py +27 -0
- ansible_aom-0.102.13/src/ansible_aom/core/stderr_classifier.py +305 -0
- ansible_aom-0.102.13/src/ansible_aom/core/text.py +15 -0
- ansible_aom-0.102.13/src/ansible_aom/core/timestamp.py +40 -0
- ansible_aom-0.102.13/src/ansible_aom/core/tree.py +153 -0
- ansible_aom-0.102.13/src/ansible_aom/core/tree_projection.py +3108 -0
- ansible_aom-0.102.13/src/ansible_aom/drivers/__init__.py +10 -0
- ansible_aom-0.102.13/src/ansible_aom/drivers/live.py +56 -0
- ansible_aom-0.102.13/src/ansible_aom/drivers/protocol.py +44 -0
- ansible_aom-0.102.13/src/ansible_aom/drivers/replay.py +252 -0
- ansible_aom-0.102.13/src/ansible_aom/formats/__init__.py +6 -0
- ansible_aom-0.102.13/src/ansible_aom/formats/json.py +258 -0
- ansible_aom-0.102.13/src/ansible_aom/inspect/__init__.py +1 -0
- ansible_aom-0.102.13/src/ansible_aom/inspect/cli.py +354 -0
- ansible_aom-0.102.13/src/ansible_aom/inspect/formatters.py +337 -0
- ansible_aom-0.102.13/src/ansible_aom/inspect/text.py +380 -0
- ansible_aom-0.102.13/src/ansible_aom/renderer/__init__.py +1 -0
- ansible_aom-0.102.13/src/ansible_aom/renderer/factory.py +63 -0
- ansible_aom-0.102.13/src/ansible_aom/renderer/protocol.py +251 -0
- ansible_aom-0.102.13/src/ansible_aom/rerun/__init__.py +1 -0
- ansible_aom-0.102.13/src/ansible_aom/rerun/cli.py +466 -0
- ansible_aom-0.102.13/src/ansible_aom/session/__init__.py +10 -0
- ansible_aom-0.102.13/src/ansible_aom/session/history.py +361 -0
- ansible_aom-0.102.13/src/ansible_aom/session/index.py +711 -0
- ansible_aom-0.102.13/src/ansible_aom/session/store.py +915 -0
- ansible_aom-0.102.13/src/ansible_aom/session/summary.py +124 -0
- ansible_aom-0.102.13/src/ansible_aom/tui/__init__.py +1 -0
- ansible_aom-0.102.13/src/ansible_aom/tui/screens/__init__.py +1 -0
- ansible_aom-0.102.13/src/ansible_aom/tui/screens/inspect.py +1646 -0
- ansible_aom-0.102.13/tests/__init__.py +0 -0
- ansible_aom-0.102.13/tests/_utils.py +94 -0
- ansible_aom-0.102.13/tests/compact/__init__.py +0 -0
- ansible_aom-0.102.13/tests/compact/golden/all_skipped__80x24.txt +11 -0
- ansible_aom-0.102.13/tests/compact/golden/all_unreachable__80x24.txt +13 -0
- ansible_aom-0.102.13/tests/compact/golden/cancelled__80x24.txt +8 -0
- ansible_aom-0.102.13/tests/compact/golden/dry_run_check__80x24.txt +7 -0
- ansible_aom-0.102.13/tests/compact/golden/empty_run__80x24.txt +1 -0
- ansible_aom-0.102.13/tests/compact/golden/multi_host_mixed__80x24.txt +27 -0
- ansible_aom-0.102.13/tests/compact/golden/multiple_plays__80x24.txt +16 -0
- ansible_aom-0.102.13/tests/compact/golden/playbook_failed__80x24.txt +12 -0
- ansible_aom-0.102.13/tests/compact/golden/single_task_ok__80x24.txt +7 -0
- ansible_aom-0.102.13/tests/compact/golden/unknown_event_type__80x24.txt +8 -0
- ansible_aom-0.102.13/tests/compact/test_ascii_fallback.py +111 -0
- ansible_aom-0.102.13/tests/compact/test_check_mode_chip.py +109 -0
- ansible_aom-0.102.13/tests/compact/test_completion_label.py +53 -0
- ansible_aom-0.102.13/tests/compact/test_completion_recap.py +139 -0
- ansible_aom-0.102.13/tests/compact/test_completion_summary.py +86 -0
- ansible_aom-0.102.13/tests/compact/test_display_ansi.py +119 -0
- ansible_aom-0.102.13/tests/compact/test_emit_event_log_batching.py +209 -0
- ansible_aom-0.102.13/tests/compact/test_error_message_extraction.py +373 -0
- ansible_aom-0.102.13/tests/compact/test_fanout_summary.py +121 -0
- ansible_aom-0.102.13/tests/compact/test_free_strategy_task_header.py +91 -0
- ansible_aom-0.102.13/tests/compact/test_full_completion_summary.py +227 -0
- ansible_aom-0.102.13/tests/compact/test_golden_frames.py +564 -0
- ansible_aom-0.102.13/tests/compact/test_hide_state.py +530 -0
- ansible_aom-0.102.13/tests/compact/test_host_table.py +207 -0
- ansible_aom-0.102.13/tests/compact/test_incremental_counters.py +98 -0
- ansible_aom-0.102.13/tests/compact/test_inspect_text_golden.py +207 -0
- ansible_aom-0.102.13/tests/compact/test_log_flush_batching.py +177 -0
- ansible_aom-0.102.13/tests/compact/test_long_output_cap.py +122 -0
- ansible_aom-0.102.13/tests/compact/test_loop_item_lines.py +213 -0
- ansible_aom-0.102.13/tests/compact/test_loop_item_streaming.py +389 -0
- ansible_aom-0.102.13/tests/compact/test_mitogen_robustness.py +226 -0
- ansible_aom-0.102.13/tests/compact/test_password.py +505 -0
- ansible_aom-0.102.13/tests/compact/test_per_task_timing.py +236 -0
- ansible_aom-0.102.13/tests/compact/test_preflight_summary.py +230 -0
- ansible_aom-0.102.13/tests/compact/test_preserve_tree_on_cancel.py +98 -0
- ansible_aom-0.102.13/tests/compact/test_prior_denominator.py +130 -0
- ansible_aom-0.102.13/tests/compact/test_prior_run_line.py +110 -0
- ansible_aom-0.102.13/tests/compact/test_render_dirty_flag.py +178 -0
- ansible_aom-0.102.13/tests/compact/test_render_preflight_scaling.py +155 -0
- ansible_aom-0.102.13/tests/compact/test_renderer_set_definitions.py +116 -0
- ansible_aom-0.102.13/tests/compact/test_renderer_stats.py +98 -0
- ansible_aom-0.102.13/tests/compact/test_row_count.py +132 -0
- ansible_aom-0.102.13/tests/compact/test_skipped_collapsing.py +186 -0
- ansible_aom-0.102.13/tests/compact/test_small_terminal.py +285 -0
- ansible_aom-0.102.13/tests/compact/test_spinner_animation.py +80 -0
- ansible_aom-0.102.13/tests/compact/test_stale_task_suffix.py +99 -0
- ansible_aom-0.102.13/tests/compact/test_status_bar_colors.py +252 -0
- ansible_aom-0.102.13/tests/compact/test_status_bar_estimated_total.py +38 -0
- ansible_aom-0.102.13/tests/compact/test_status_bar_eta.py +41 -0
- ansible_aom-0.102.13/tests/compact/test_status_bar_liveness.py +270 -0
- ansible_aom-0.102.13/tests/compact/test_status_tally_bar.py +139 -0
- ansible_aom-0.102.13/tests/compact/test_summary_flush_scaling.py +168 -0
- ansible_aom-0.102.13/tests/compact/test_task_progress.py +353 -0
- ansible_aom-0.102.13/tests/compact/test_task_summary.py +301 -0
- ansible_aom-0.102.13/tests/compact/test_task_summary_calculation.py +164 -0
- ansible_aom-0.102.13/tests/compact/test_tree_event_replay.py +230 -0
- ansible_aom-0.102.13/tests/compact/test_tree_large_playbook.py +216 -0
- ansible_aom-0.102.13/tests/compact/test_tree_pipe_continuation.py +568 -0
- ansible_aom-0.102.13/tests/compact/test_tree_projection_lifecycle.py +210 -0
- ansible_aom-0.102.13/tests/compact/test_tree_render.py +949 -0
- ansible_aom-0.102.13/tests/compact/test_tree_upcoming_plays.py +209 -0
- ansible_aom-0.102.13/tests/compact/test_tree_upcoming_tasks.py +150 -0
- ansible_aom-0.102.13/tests/compact/test_unknown_event_hint.py +125 -0
- ansible_aom-0.102.13/tests/compact/test_unmatched_event_hint.py +47 -0
- ansible_aom-0.102.13/tests/compact/test_warning_color.py +59 -0
- ansible_aom-0.102.13/tests/compact/test_warning_visibility.py +91 -0
- ansible_aom-0.102.13/tests/conftest.py +300 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/dynamic_target.yml +10 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/ignore_errors.yml +13 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/imported_tasks.yml +7 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/included_tasks.yml +7 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/missing_role.yml +5 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/multi_hosts.yml +8 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/multi_play.yml +21 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/nested_level1.yml +6 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/nested_level2.yml +7 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/no_name.yml +11 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/roles/angie_ssl_terminator/tasks/main.yml +31 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/roles/podman/tasks/main.yml +24 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/roles/podman_role_rel/tasks/_includes/setup.yml +8 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/roles/podman_role_rel/tasks/main.yml +15 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/roles/test_role/tasks/main.yml +11 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/simple.yml +16 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/syntax_error.yml +10 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/unreachable.yml +15 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_block.yml +20 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_dynamic_include.yml +7 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_import.yml +13 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_include.yml +10 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_include_role.yml +14 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_loop.yml +12 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_nested_include.yml +10 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_nested_role.yml +8 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_pre_post.yml +21 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_role.yml +10 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_role_rel_include.yml +6 -0
- ansible_aom-0.102.13/tests/fixtures/ansible/with_throttle.yml +9 -0
- ansible_aom-0.102.13/tests/fixtures/multi_host_mixed.jsonl +13 -0
- ansible_aom-0.102.13/tests/fixtures/playbook_failed.jsonl +7 -0
- ansible_aom-0.102.13/tests/fixtures/redaction_bypass.jsonl +34 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4000-0000-7000-8000-000000000001/events.jsonl +7 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4000-0000-7000-8000-000000000001/meta.json +10 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4100-0000-7000-8000-000000000003/events.jsonl +7 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4100-0000-7000-8000-000000000003/meta.json +10 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4200-0000-7000-8000-000000000004/events.jsonl +5 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4200-0000-7000-8000-000000000004/meta.json +10 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4300-0000-7000-8000-000000000005/events.jsonl +3 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4300-0000-7000-8000-000000000005/meta.json +7 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4520-fa64-7000-a627-000000000002/events.jsonl +7 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4520-fa64-7000-a627-000000000002/meta.json +10 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4520-fa64-7000-a627-000000000002/stderr.log +14 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4600-0000-7000-8000-000000000006/events.jsonl +8 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/019e4600-0000-7000-8000-000000000006/meta.json +10 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/__init__.py +0 -0
- ansible_aom-0.102.13/tests/fixtures/sessions/conftest.py +75 -0
- ansible_aom-0.102.13/tests/fixtures/single_task_ok.jsonl +5 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/connection_multi_host.jsonl +4 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/connection_sequential_host.jsonl +4 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/connection_simple_cycle.jsonl +2 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/mixed_playbook_with_stderr.jsonl +10 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/overlap_different_hosts_unique.jsonl +5 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/overlap_no_active_connection.jsonl +3 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/overlap_same_host_ambiguous.jsonl +5 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/overlap_three_same_host.jsonl +7 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_connection.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_connection_lifecycle.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_deprecation.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_error.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_inventory.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_plugin_loading.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_prompt.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_run_level.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_ssh_debug.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_ssh_info.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_unknown.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_vault.jsonl +1 -0
- ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_warning.jsonl +1 -0
- ansible_aom-0.102.13/tests/integration/__init__.py +4 -0
- ansible_aom-0.102.13/tests/integration/test_compact_renderer.py +1203 -0
- ansible_aom-0.102.13/tests/integration/test_concurrent_inspect.py +526 -0
- ansible_aom-0.102.13/tests/integration/test_ctrl_c_race.py +182 -0
- ansible_aom-0.102.13/tests/integration/test_error_handling.py +574 -0
- ansible_aom-0.102.13/tests/integration/test_fixture_layout.py +16 -0
- ansible_aom-0.102.13/tests/integration/test_history_roundtrip.py +186 -0
- ansible_aom-0.102.13/tests/integration/test_ignore_errors_callback.py +106 -0
- ansible_aom-0.102.13/tests/integration/test_include_import_role.py +270 -0
- ansible_aom-0.102.13/tests/integration/test_inspect_cli.py +260 -0
- ansible_aom-0.102.13/tests/integration/test_invariants_session_roundtrip.py +310 -0
- ansible_aom-0.102.13/tests/integration/test_loop_item_events.py +187 -0
- ansible_aom-0.102.13/tests/integration/test_meta_task_callback.py +249 -0
- ansible_aom-0.102.13/tests/integration/test_no_eof_hang.py +134 -0
- ansible_aom-0.102.13/tests/integration/test_no_record.py +70 -0
- ansible_aom-0.102.13/tests/integration/test_playbook_parser.py +1050 -0
- ansible_aom-0.102.13/tests/integration/test_preflight_runner.py +280 -0
- ansible_aom-0.102.13/tests/integration/test_r6_encoding_roundtrip.py +259 -0
- ansible_aom-0.102.13/tests/integration/test_real_ansible.py +232 -0
- ansible_aom-0.102.13/tests/integration/test_redaction.py +978 -0
- ansible_aom-0.102.13/tests/integration/test_renderer_eta.py +271 -0
- ansible_aom-0.102.13/tests/integration/test_renderer_parity.py +119 -0
- ansible_aom-0.102.13/tests/integration/test_replay.py +110 -0
- ansible_aom-0.102.13/tests/integration/test_replay_determinism.py +471 -0
- ansible_aom-0.102.13/tests/integration/test_rerun.py +140 -0
- ansible_aom-0.102.13/tests/integration/test_rerun_roundtrip.py +462 -0
- ansible_aom-0.102.13/tests/integration/test_runner.py +265 -0
- ansible_aom-0.102.13/tests/integration/test_runner_interactive_prompts.py +513 -0
- ansible_aom-0.102.13/tests/integration/test_runner_on_start_host.py +103 -0
- ansible_aom-0.102.13/tests/integration/test_runner_session_recording.py +295 -0
- ansible_aom-0.102.13/tests/integration/test_session.py +919 -0
- ansible_aom-0.102.13/tests/integration/test_throttle.py +318 -0
- ansible_aom-0.102.13/tests/playbooks/01-single-task-success/site.yml +8 -0
- ansible_aom-0.102.13/tests/playbooks/02-single-task-changed/cleanup.sh +2 -0
- ansible_aom-0.102.13/tests/playbooks/02-single-task-changed/site.yml +10 -0
- ansible_aom-0.102.13/tests/playbooks/03-task-failure/site.yml +12 -0
- ansible_aom-0.102.13/tests/playbooks/04-ignore-errors/site.yml +13 -0
- ansible_aom-0.102.13/tests/playbooks/05-skipped-tasks/site.yml +15 -0
- ansible_aom-0.102.13/tests/playbooks/06-unreachable/site.yml +7 -0
- ansible_aom-0.102.13/tests/playbooks/07-multi-host-mixed/site.yml +20 -0
- ansible_aom-0.102.13/tests/playbooks/08-multiple-plays/site.yml +35 -0
- ansible_aom-0.102.13/tests/playbooks/09-handler-tasks/cleanup.sh +2 -0
- ansible_aom-0.102.13/tests/playbooks/09-handler-tasks/site.yml +16 -0
- ansible_aom-0.102.13/tests/playbooks/10-free-strategy/site.yml +13 -0
- ansible_aom-0.102.13/tests/playbooks/11-role-grouping/roles/nginx/tasks/main.yml +22 -0
- ansible_aom-0.102.13/tests/playbooks/11-role-grouping/site.yml +6 -0
- ansible_aom-0.102.13/tests/playbooks/12-vault-encrypted/README.md +39 -0
- ansible_aom-0.102.13/tests/playbooks/12-vault-encrypted/site.yml +10 -0
- ansible_aom-0.102.13/tests/playbooks/12-vault-encrypted/vars/secrets.yml +2 -0
- ansible_aom-0.102.13/tests/playbooks/13-ssh-password/README.md +25 -0
- ansible_aom-0.102.13/tests/playbooks/13-ssh-password/site.yml +8 -0
- ansible_aom-0.102.13/tests/playbooks/14-become-password/README.md +29 -0
- ansible_aom-0.102.13/tests/playbooks/14-become-password/site.yml +9 -0
- ansible_aom-0.102.13/tests/playbooks/15-vault-password-change/README.md +38 -0
- ansible_aom-0.102.13/tests/playbooks/16-warnings/site.yml +8 -0
- ansible_aom-0.102.13/tests/playbooks/17-deprecation-warnings/site.yml +11 -0
- ansible_aom-0.102.13/tests/playbooks/17-deprecation-warnings/tasks/subtask.yml +4 -0
- ansible_aom-0.102.13/tests/playbooks/18-no-log-redaction/site.yml +23 -0
- ansible_aom-0.102.13/tests/playbooks/19-password-field-redaction/site.yml +24 -0
- ansible_aom-0.102.13/tests/playbooks/20-url-cli-credential-redaction/site.yml +20 -0
- ansible_aom-0.102.13/tests/playbooks/21-module-args-redaction/site.yml +21 -0
- ansible_aom-0.102.13/tests/playbooks/22-play-recap/site.yml +12 -0
- ansible_aom-0.102.13/tests/playbooks/23-command-not-found/README.md +17 -0
- ansible_aom-0.102.13/tests/playbooks/24-user-cancellation/site.yml +7 -0
- ansible_aom-0.102.13/tests/playbooks/25-syntax-error/site.yml +9 -0
- ansible_aom-0.102.13/tests/playbooks/26-empty-playbook/site.yml +5 -0
- ansible_aom-0.102.13/tests/playbooks/27-single-host-localhost/site.yml +9 -0
- ansible_aom-0.102.13/tests/playbooks/28-host-pattern-filtering/site.yml +8 -0
- ansible_aom-0.102.13/tests/playbooks/29-tags/site.yml +24 -0
- ansible_aom-0.102.13/tests/playbooks/30-include-vs-import/site.yml +10 -0
- ansible_aom-0.102.13/tests/playbooks/30-include-vs-import/tasks/dynamic.yml +7 -0
- ansible_aom-0.102.13/tests/playbooks/30-include-vs-import/tasks/static.yml +7 -0
- ansible_aom-0.102.13/tests/playbooks/31-block-tasks/site.yml +31 -0
- ansible_aom-0.102.13/tests/playbooks/32-large-playbook/generate.py +16 -0
- ansible_aom-0.102.13/tests/playbooks/33-mixed-warnings-execution/site.yml +23 -0
- ansible_aom-0.102.13/tests/playbooks/ansible.cfg +5 -0
- ansible_aom-0.102.13/tests/playbooks/inventory.ini +19 -0
- ansible_aom-0.102.13/tests/tui/__init__.py +0 -0
- ansible_aom-0.102.13/tests/tui/test_inspect_screen.py +1430 -0
- ansible_aom-0.102.13/tests/tui/test_panels.py +1475 -0
- ansible_aom-0.102.13/tests/unit/test_aom_connection.py +168 -0
- ansible_aom-0.102.13/tests/unit/test_aom_trace_events.py +80 -0
- ansible_aom-0.102.13/tests/unit/test_aom_verbose_line_fuzz.py +205 -0
- ansible_aom-0.102.13/tests/unit/test_async_preflight.py +64 -0
- ansible_aom-0.102.13/tests/unit/test_build_configuration.py +93 -0
- ansible_aom-0.102.13/tests/unit/test_bump_version.py +277 -0
- ansible_aom-0.102.13/tests/unit/test_callback_env.py +167 -0
- ansible_aom-0.102.13/tests/unit/test_check_version_bump.py +320 -0
- ansible_aom-0.102.13/tests/unit/test_cli.py +1862 -0
- ansible_aom-0.102.13/tests/unit/test_cli_duplicate_playbook.py +35 -0
- ansible_aom-0.102.13/tests/unit/test_cli_inventory_autodetect.py +92 -0
- ansible_aom-0.102.13/tests/unit/test_cli_limit_merge.py +97 -0
- ansible_aom-0.102.13/tests/unit/test_cli_matrix.py +75 -0
- ansible_aom-0.102.13/tests/unit/test_cli_replay.py +143 -0
- ansible_aom-0.102.13/tests/unit/test_cli_tui_launch.py +26 -0
- ansible_aom-0.102.13/tests/unit/test_compact_pause_visibility.py +115 -0
- ansible_aom-0.102.13/tests/unit/test_completion.py +184 -0
- ansible_aom-0.102.13/tests/unit/test_config.py +737 -0
- ansible_aom-0.102.13/tests/unit/test_config_layer.py +420 -0
- ansible_aom-0.102.13/tests/unit/test_core_text.py +24 -0
- ansible_aom-0.102.13/tests/unit/test_diagnostics.py +143 -0
- ansible_aom-0.102.13/tests/unit/test_diagnostics_summary_print.py +82 -0
- ansible_aom-0.102.13/tests/unit/test_diagnostics_wiring.py +81 -0
- ansible_aom-0.102.13/tests/unit/test_distribution.py +139 -0
- ansible_aom-0.102.13/tests/unit/test_duration.py +55 -0
- ansible_aom-0.102.13/tests/unit/test_dynamic_counters.py +570 -0
- ansible_aom-0.102.13/tests/unit/test_dynamic_expansion.py +1015 -0
- ansible_aom-0.102.13/tests/unit/test_encoding_robustness.py +134 -0
- ansible_aom-0.102.13/tests/unit/test_estimate.py +206 -0
- ansible_aom-0.102.13/tests/unit/test_event_processing.py +2148 -0
- ansible_aom-0.102.13/tests/unit/test_event_source.py +284 -0
- ansible_aom-0.102.13/tests/unit/test_event_store_crash_recovery.py +499 -0
- ansible_aom-0.102.13/tests/unit/test_heartbeat.py +241 -0
- ansible_aom-0.102.13/tests/unit/test_history.py +401 -0
- ansible_aom-0.102.13/tests/unit/test_history_loop_totals.py +117 -0
- ansible_aom-0.102.13/tests/unit/test_history_observed_count.py +156 -0
- ansible_aom-0.102.13/tests/unit/test_history_task_wall.py +209 -0
- ansible_aom-0.102.13/tests/unit/test_host_resolution.py +457 -0
- ansible_aom-0.102.13/tests/unit/test_icons.py +508 -0
- ansible_aom-0.102.13/tests/unit/test_include_cache.py +1686 -0
- ansible_aom-0.102.13/tests/unit/test_inspect_accumulator.py +280 -0
- ansible_aom-0.102.13/tests/unit/test_inspect_changes.py +221 -0
- ansible_aom-0.102.13/tests/unit/test_inspect_debug.py +241 -0
- ansible_aom-0.102.13/tests/unit/test_inspect_index_wiring.py +160 -0
- ansible_aom-0.102.13/tests/unit/test_inspect_model.py +650 -0
- ansible_aom-0.102.13/tests/unit/test_inspect_model_verbose.py +150 -0
- ansible_aom-0.102.13/tests/unit/test_inspect_prune.py +49 -0
- ansible_aom-0.102.13/tests/unit/test_inspect_warnings.py +118 -0
- ansible_aom-0.102.13/tests/unit/test_interactive_prompt.py +137 -0
- ansible_aom-0.102.13/tests/unit/test_invariants_runstate_renderer.py +363 -0
- ansible_aom-0.102.13/tests/unit/test_json_renderer.py +450 -0
- ansible_aom-0.102.13/tests/unit/test_layering.py +178 -0
- ansible_aom-0.102.13/tests/unit/test_linear_dead_host_synthesis.py +301 -0
- ansible_aom-0.102.13/tests/unit/test_log_filter.py +326 -0
- ansible_aom-0.102.13/tests/unit/test_loop_item_count.py +124 -0
- ansible_aom-0.102.13/tests/unit/test_meta_schema_version.py +144 -0
- ansible_aom-0.102.13/tests/unit/test_models.py +1631 -0
- ansible_aom-0.102.13/tests/unit/test_no_record.py +108 -0
- ansible_aom-0.102.13/tests/unit/test_overhead.py +234 -0
- ansible_aom-0.102.13/tests/unit/test_overhead_display.py +115 -0
- ansible_aom-0.102.13/tests/unit/test_parser.py +2033 -0
- ansible_aom-0.102.13/tests/unit/test_parser_orjson_swap.py +88 -0
- ansible_aom-0.102.13/tests/unit/test_parser_recap_cap.py +60 -0
- ansible_aom-0.102.13/tests/unit/test_pause_lingering_cleanup.py +123 -0
- ansible_aom-0.102.13/tests/unit/test_pause_prompt_reconstruction.py +168 -0
- ansible_aom-0.102.13/tests/unit/test_play_boundary_state.py +343 -0
- ansible_aom-0.102.13/tests/unit/test_poll_and_retry_hint.py +124 -0
- ansible_aom-0.102.13/tests/unit/test_posix_callback.py +303 -0
- ansible_aom-0.102.13/tests/unit/test_pre_push.py +46 -0
- ansible_aom-0.102.13/tests/unit/test_preflight.py +150 -0
- ansible_aom-0.102.13/tests/unit/test_prior_run_loop_totals_injection.py +41 -0
- ansible_aom-0.102.13/tests/unit/test_profile_tracemalloc.py +104 -0
- ansible_aom-0.102.13/tests/unit/test_properties_parser.py +198 -0
- ansible_aom-0.102.13/tests/unit/test_properties_redaction.py +237 -0
- ansible_aom-0.102.13/tests/unit/test_properties_state.py +246 -0
- ansible_aom-0.102.13/tests/unit/test_psutil_safe_probe.py +111 -0
- ansible_aom-0.102.13/tests/unit/test_pty_stream.py +894 -0
- ansible_aom-0.102.13/tests/unit/test_publication_docs.py +83 -0
- ansible_aom-0.102.13/tests/unit/test_redaction.py +1064 -0
- ansible_aom-0.102.13/tests/unit/test_redaction_layer4.py +425 -0
- ansible_aom-0.102.13/tests/unit/test_redaction_redteam_fixture.py +162 -0
- ansible_aom-0.102.13/tests/unit/test_render_storm.py +75 -0
- ansible_aom-0.102.13/tests/unit/test_renderer_stats_parity.py +51 -0
- ansible_aom-0.102.13/tests/unit/test_renderer_unbounded_caps.py +91 -0
- ansible_aom-0.102.13/tests/unit/test_replay.py +320 -0
- ansible_aom-0.102.13/tests/unit/test_replay_schema_boundary.py +410 -0
- ansible_aom-0.102.13/tests/unit/test_rerun_cli.py +703 -0
- ansible_aom-0.102.13/tests/unit/test_run_config.py +143 -0
- ansible_aom-0.102.13/tests/unit/test_run_diagnostics.py +214 -0
- ansible_aom-0.102.13/tests/unit/test_run_state_index.py +239 -0
- ansible_aom-0.102.13/tests/unit/test_run_state_memory_bounds.py +210 -0
- ansible_aom-0.102.13/tests/unit/test_run_state_set_caps.py +85 -0
- ansible_aom-0.102.13/tests/unit/test_run_summary_schema.py +273 -0
- ansible_aom-0.102.13/tests/unit/test_runner_ctrl_c_race.py +210 -0
- ansible_aom-0.102.13/tests/unit/test_runner_eof_watchdog.py +306 -0
- ansible_aom-0.102.13/tests/unit/test_runner_event_fallback.py +644 -0
- ansible_aom-0.102.13/tests/unit/test_runner_events_recorded.py +296 -0
- ansible_aom-0.102.13/tests/unit/test_runner_heartbeat.py +127 -0
- ansible_aom-0.102.13/tests/unit/test_runner_isalive_in_loop.py +205 -0
- ansible_aom-0.102.13/tests/unit/test_runner_prompt_echo.py +53 -0
- ansible_aom-0.102.13/tests/unit/test_runner_searchwindowsize.py +156 -0
- ansible_aom-0.102.13/tests/unit/test_runner_session_footer.py +29 -0
- ansible_aom-0.102.13/tests/unit/test_runner_session_meta.py +46 -0
- ansible_aom-0.102.13/tests/unit/test_runner_stall_flush.py +424 -0
- ansible_aom-0.102.13/tests/unit/test_runner_watchdog_endtime.py +192 -0
- ansible_aom-0.102.13/tests/unit/test_runtime_role_task_count.py +326 -0
- ansible_aom-0.102.13/tests/unit/test_session_collectors.py +192 -0
- ansible_aom-0.102.13/tests/unit/test_session_diagnostics.py +136 -0
- ansible_aom-0.102.13/tests/unit/test_session_helpers.py +97 -0
- ansible_aom-0.102.13/tests/unit/test_session_index.py +801 -0
- ansible_aom-0.102.13/tests/unit/test_session_meta_persistence.py +33 -0
- ansible_aom-0.102.13/tests/unit/test_session_store_async_write.py +229 -0
- ansible_aom-0.102.13/tests/unit/test_sink_disable_and_preflight_ms.py +76 -0
- ansible_aom-0.102.13/tests/unit/test_stale_running_cleanup.py +281 -0
- ansible_aom-0.102.13/tests/unit/test_state_dir_isolation.py +23 -0
- ansible_aom-0.102.13/tests/unit/test_status_tally.py +85 -0
- ansible_aom-0.102.13/tests/unit/test_stderr_classifier.py +852 -0
- ansible_aom-0.102.13/tests/unit/test_task_completion.py +218 -0
- ansible_aom-0.102.13/tests/unit/test_template_variable_names.py +732 -0
- ansible_aom-0.102.13/tests/unit/test_tree_classify_and_role_labels.py +2309 -0
- ansible_aom-0.102.13/tests/unit/test_tree_meta_hostless.py +198 -0
- ansible_aom-0.102.13/tests/unit/test_tree_nested_role_order_stability.py +578 -0
- ansible_aom-0.102.13/tests/unit/test_tree_nested_roles.py +1272 -0
- ansible_aom-0.102.13/tests/unit/test_tree_projection.py +6576 -0
- ansible_aom-0.102.13/tests/unit/test_tree_ungrouped_roles.py +613 -0
- ansible_aom-0.102.13/tests/unit/test_verify_anchors.py +416 -0
- ansible_aom-0.102.13/tests/unit/test_version_consistency.py +47 -0
- ansible_aom-0.102.13/tests/unit/test_versioning.py +11 -0
- ansible_aom-0.102.13/tests/unit/test_warnings.py +315 -0
- ansible_aom-0.102.13/uv.lock +1874 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# graphify-refresh: AST-only refresh of the knowledge graph artifacts.
|
|
3
|
+
#
|
|
4
|
+
# The graph is generated from the MAIN aom repo's source, so
|
|
5
|
+
# `graphify update .` / cluster-only / tree / export wiki run at the repo
|
|
6
|
+
# root. graphify writes its artifacts into graphify-out/, which is a git
|
|
7
|
+
# submodule owning its own repository — so the regenerated files live in
|
|
8
|
+
# that submodule repo and never pollute aom's PR diff.
|
|
9
|
+
#
|
|
10
|
+
# Flow:
|
|
11
|
+
# 1. Ensure the graphify-out submodule is checked out.
|
|
12
|
+
# 2. Regenerate artifacts from the main repo root (they land inside the
|
|
13
|
+
# submodule worktree).
|
|
14
|
+
# 3. Commit + push inside the submodule (best-effort).
|
|
15
|
+
# 4. Stage the updated submodule pointer (gitlink) in the superproject,
|
|
16
|
+
# so aom's diff stays a single line per regeneration.
|
|
17
|
+
# Skips gracefully if graphify-out/ is not initialized or the CLI is missing.
|
|
18
|
+
set -e
|
|
19
|
+
|
|
20
|
+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo ".")"
|
|
21
|
+
cd "$REPO_ROOT"
|
|
22
|
+
|
|
23
|
+
if [ ! -d graphify-out ] || [ ! -f graphify-out/graph.json ]; then
|
|
24
|
+
echo "graphify-out/ not initialized, skipping graph refresh"
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
if ! command -v graphify >/dev/null 2>&1; then
|
|
29
|
+
echo "graphify CLI not found, skipping graph refresh"
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Ensure the submodule is populated so graphify-out is a real git repo.
|
|
34
|
+
git submodule update --init graphify-out 2>/dev/null || true
|
|
35
|
+
|
|
36
|
+
# Raise HTML viz node limit. Default (5000) is too small for this repo's
|
|
37
|
+
# ~12k-node graph. Override locally with `GRAPHIFY_VIZ_NODE_LIMIT=... git commit`.
|
|
38
|
+
export GRAPHIFY_VIZ_NODE_LIMIT="${GRAPHIFY_VIZ_NODE_LIMIT:-20000}"
|
|
39
|
+
|
|
40
|
+
# NixOS: graphify needs numpy which needs libstdc++.so.6.
|
|
41
|
+
# If it's not on the default LD_LIBRARY_PATH, try to add it.
|
|
42
|
+
if ! python3 -c "import numpy" 2>/dev/null; then
|
|
43
|
+
_LIBSTDCXX="$(gcc -print-file-name=libstdc++.so.6 2>/dev/null || true)"
|
|
44
|
+
if [ -n "$_LIBSTDCXX" ] && [ -f "$_LIBSTDCXX" ]; then
|
|
45
|
+
_LIBDIR="$(dirname "$_LIBSTDCXX")"
|
|
46
|
+
export LD_LIBRARY_PATH="${_LIBDIR}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Generate against the main repo source. Artifacts land in graphify-out/
|
|
51
|
+
# (the submodule worktree).
|
|
52
|
+
graphify install 2>/dev/null || true
|
|
53
|
+
graphify update . || exit 1
|
|
54
|
+
graphify cluster-only . 2>/dev/null || true
|
|
55
|
+
graphify tree 2>/dev/null || true
|
|
56
|
+
|
|
57
|
+
if [ -f graphify-out/graph.json ]; then
|
|
58
|
+
graphify export wiki 2>/dev/null || true
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Commit + push the refreshed artifacts inside the submodule.
|
|
62
|
+
if git -C graphify-out rev-parse --git-dir >/dev/null 2>&1 \
|
|
63
|
+
&& git -C graphify-out remote >/dev/null 2>&1; then
|
|
64
|
+
if ! git -C graphify-out diff --quiet; then
|
|
65
|
+
git -C graphify-out add -u \
|
|
66
|
+
graph.json \
|
|
67
|
+
.graphify_labels.json \
|
|
68
|
+
.graphify_analysis.json \
|
|
69
|
+
.graphify_semantic_marker \
|
|
70
|
+
GRAPH_TREE.html \
|
|
71
|
+
GRAPH_REPORT.md \
|
|
72
|
+
graph.html \
|
|
73
|
+
wiki/ 2>/dev/null || true
|
|
74
|
+
git -C graphify-out commit -m "chore: regenerate graph artifacts" >/dev/null 2>&1 || true
|
|
75
|
+
# Push is best-effort; a missing/denied remote must not fail the commit.
|
|
76
|
+
git -C graphify-out push 2>/dev/null \
|
|
77
|
+
|| echo "graphify: submodule push skipped (no reachable remote)"
|
|
78
|
+
fi
|
|
79
|
+
else
|
|
80
|
+
echo "graphify: submodule repo/remote not present, artifacts left uncommitted"
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Stage the updated submodule pointer (gitlink) in the superproject.
|
|
84
|
+
git add graphify-out 2>/dev/null || true
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Wrapper to invoke pre-commit from a custom git hooks path.
|
|
3
|
+
# Installed by the shell hook when global core.hooksPath is set to a
|
|
4
|
+
# non-default location; pre-commit itself cannot target a custom path.
|
|
5
|
+
exec pre-commit run --hook-stage pre-commit "$@"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
# ansible-lint config for AOM test playbooks
|
|
3
|
+
# These playbooks are intentionally minimal test fixtures for a monitoring tool,
|
|
4
|
+
# not production roles. Rules are lenient accordingly.
|
|
5
|
+
|
|
6
|
+
schema: basic
|
|
7
|
+
|
|
8
|
+
offline: true
|
|
9
|
+
|
|
10
|
+
warn_list:
|
|
11
|
+
- name[missing]
|
|
12
|
+
- name[casing]
|
|
13
|
+
- name[template]
|
|
14
|
+
- var-naming[no-role-prefix]
|
|
15
|
+
|
|
16
|
+
skip_list:
|
|
17
|
+
- no-changed-when # test tasks use debug/command intentionally
|
|
18
|
+
- no-handler # test playbooks don't need handler patterns
|
|
19
|
+
- risky-shell-pipe # test shell tasks are intentionally simple
|
|
20
|
+
- command-instead-of-shell # test tasks favor simplicity over best practice
|
|
21
|
+
- command-instead-of-module # test tasks use command for predictability
|
|
22
|
+
|
|
23
|
+
exclude_paths:
|
|
24
|
+
- tests/playbooks/32-large-playbook/ # generated playbook
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(uv sync:*)",
|
|
5
|
+
"Bash(uv run:*)",
|
|
6
|
+
"Bash(uv pip:*)",
|
|
7
|
+
"Bash(git:*)",
|
|
8
|
+
"Bash(ansible-galaxy:*)",
|
|
9
|
+
"Bash(ansible-playbook:*)",
|
|
10
|
+
"Bash(mkdir:*)",
|
|
11
|
+
"Bash(rm:*)",
|
|
12
|
+
"Read",
|
|
13
|
+
"Write",
|
|
14
|
+
"Edit",
|
|
15
|
+
"Glob",
|
|
16
|
+
"Grep",
|
|
17
|
+
"WebSearch",
|
|
18
|
+
"WebFetch"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"hooks": {
|
|
22
|
+
"PostToolUse": [
|
|
23
|
+
{
|
|
24
|
+
"matcher": "Edit|Write",
|
|
25
|
+
"hooks": [
|
|
26
|
+
{
|
|
27
|
+
"type": "command",
|
|
28
|
+
"command": "f=$(jq -r '.tool_input.file_path // .tool_response.filePath // empty'); case \"$f\" in *.py) uv run ruff format --check \"$f\" >/dev/null 2>&1 && uv run ruff check \"$f\" >/dev/null 2>&1 ;; esac"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"env": {
|
|
35
|
+
"ANSIBLE_STDOUT_CALLBACK": "ansible.posix.jsonl"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify
|
|
3
|
+
description: How to verify aom compact-renderer changes end-to-end — run aom on a real playbook under a PTY, capture raw bytes, count DEC-2026 frames and log lines.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Verifying aom at the terminal surface
|
|
7
|
+
|
|
8
|
+
The compact renderer's surface is raw stdout bytes on a TTY. Unit tests
|
|
9
|
+
capture strings; real verification needs a PTY with a controlled size
|
|
10
|
+
and a capture of the raw escape-sequence stream.
|
|
11
|
+
|
|
12
|
+
## Recipe
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# 1. A storm playbook (loop → rapid v2_runner_item_on_* events):
|
|
16
|
+
cat > /tmp/storm.yml <<'EOF'
|
|
17
|
+
- hosts: localhost
|
|
18
|
+
gather_facts: false
|
|
19
|
+
tasks:
|
|
20
|
+
- name: storm
|
|
21
|
+
ansible.builtin.debug: {msg: "item {{ item }}"}
|
|
22
|
+
loop: "{{ range(0, 120) | list }}"
|
|
23
|
+
EOF
|
|
24
|
+
|
|
25
|
+
# 2. Run under a PTY with forced size, capture raw bytes.
|
|
26
|
+
# `script` gives a real PTY; stty inside sets the winsize (without it
|
|
27
|
+
# the size is 0x0 → aom falls into degraded plain-log mode).
|
|
28
|
+
cd /tmp && script -qec "stty rows 40 cols 120; \
|
|
29
|
+
uv run --project /path/to/ansible-aom aom --no-record -y /tmp/storm.yml" \
|
|
30
|
+
/tmp/aom_raw.bin >/dev/null 2>&1
|
|
31
|
+
|
|
32
|
+
# 3. Analyze: frames = count of BSU (\x1b[?2026h); log lines via regex.
|
|
33
|
+
python3 -c "
|
|
34
|
+
data = open('/tmp/aom_raw.bin', 'rb').read().decode(errors='replace')
|
|
35
|
+
print('frames:', data.count('\x1b[?2026h'))
|
|
36
|
+
print('cursor restored:', '\x1b[?25h' in data)
|
|
37
|
+
"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## What to check
|
|
41
|
+
|
|
42
|
+
- **Frame budget**: log-batching caps repaints at ~30 Hz. A 120-item
|
|
43
|
+
storm finishing in ~1s should produce **~15–30 frames**, not 120+.
|
|
44
|
+
- **No lost/reordered lines**: every loop item appears exactly once, in
|
|
45
|
+
order. Items render as `ok: [localhost] => (item=N)`.
|
|
46
|
+
- **Cursor restored** (`\x1b[?25h`) and final status line present after
|
|
47
|
+
both clean completion and Ctrl-C.
|
|
48
|
+
- **Degraded mode**: `stty rows 10 cols 60` → "terminal too small"
|
|
49
|
+
warning, zero BSU frames, all log lines still printed plainly.
|
|
50
|
+
|
|
51
|
+
## Gotchas
|
|
52
|
+
|
|
53
|
+
- **Ctrl-C probe**: send SIGINT to the *aom python process only*
|
|
54
|
+
(`ps -ef | grep bin/aom`), never `pkill -f` a pattern matching the
|
|
55
|
+
`uv run` wrapper — killing the wrapper skips aom's cleanup AND leaks
|
|
56
|
+
orphaned `ansible-playbook` children that keep running. Expect exit
|
|
57
|
+
130 + `✖ cancelled by user` + cursor restore.
|
|
58
|
+
- `script` must run with cwd outside the repo or it happily works either
|
|
59
|
+
way, but the capture file lands wherever you point it; use /tmp.
|
|
60
|
+
- Known pre-existing quirks (don't blame your diff): loop item `0`
|
|
61
|
+
renders as `(item=)` (falsy-zero formatting), and localhost runs emit
|
|
62
|
+
a `[WARNING]: Callback dispatch 'v2_runner_on_start' failed for
|
|
63
|
+
plugin 'aom_connection'` warning.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
use flake
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# post-commit: fold repo-generated artifacts into the just-created commit.
|
|
3
|
+
#
|
|
4
|
+
# The pre-commit framework stashes-then-restores the working tree around
|
|
5
|
+
# its pre-commit hooks, silently rolling back any `git add` (and any
|
|
6
|
+
# nested submodule commit) a pre-commit hook performs — so neither the
|
|
7
|
+
# version bump nor the graphify submodule refresh can run there.
|
|
8
|
+
# post-commit runs after that machinery; each step folds its result into
|
|
9
|
+
# the commit via `git commit --amend` (env-guarded against recursion).
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
|
13
|
+
cd "$REPO_ROOT"
|
|
14
|
+
|
|
15
|
+
if [ -x scripts/bump_version.py ]; then
|
|
16
|
+
AOM_BUMP_HOOK_RUNNING="${AOM_BUMP_HOOK_RUNNING:-}" uv run scripts/bump_version.py || true
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
if [ -x .githooks/post-commit-graphify ]; then
|
|
20
|
+
.githooks/post-commit-graphify || true
|
|
21
|
+
fi
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# graphify-post-commit: refresh the knowledge graph AFTER a commit lands.
|
|
3
|
+
#
|
|
4
|
+
# Why post-commit + amend and not a pre-commit hook: the pre-commit
|
|
5
|
+
# framework stashes-then-restores the working tree around its pre-commit
|
|
6
|
+
# hooks, which silently rolls back both the graphify-out submodule commit
|
|
7
|
+
# and the gitlink `git add` this script performs. post-commit runs after
|
|
8
|
+
# that machinery is done, so the regeneration can safely commit the
|
|
9
|
+
# submodule and fold the new pointer into the same commit via
|
|
10
|
+
# `git commit --amend`.
|
|
11
|
+
#
|
|
12
|
+
# Only runs when the commit touched graph-relevant files (source, tests,
|
|
13
|
+
# docs, pyproject) so unrelated commits don't trigger a wasteful
|
|
14
|
+
# regeneration. Recursion from the amend is blocked by the
|
|
15
|
+
# AOM_GRAPHIFY_POST_COMMIT env var.
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
if [ -n "${AOM_GRAPHIFY_POST_COMMIT:-}" ]; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || exit 0)"
|
|
23
|
+
cd "$REPO_ROOT"
|
|
24
|
+
|
|
25
|
+
if [ ! -d graphify-out ] || [ ! -f graphify-out/graph.json ]; then
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
if ! command -v graphify >/dev/null 2>&1; then
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Bail out mid-rebase / mid-merge / mid-cherry-pick — an amend during
|
|
33
|
+
# those would scramble the in-flight sequencing.
|
|
34
|
+
for marker in REBASE_HEAD MERGE_HEAD CHERRY_PICK_HEAD BISECT_LOG; do
|
|
35
|
+
if [ -f "$REPO_ROOT/.git/$marker" ]; then
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
# git sets GIT_DIR / GIT_INDEX_FILE when it runs hooks, which makes
|
|
41
|
+
# `git -C graphify-out ...` resolve the superproject's gitdir instead of
|
|
42
|
+
# the submodule's. Unset them so submodule commands address the right
|
|
43
|
+
# repo.
|
|
44
|
+
unset GIT_DIR GIT_INDEX_FILE GIT_WORK_TREE 2>/dev/null || true
|
|
45
|
+
|
|
46
|
+
# Only regenerate when HEAD touched graph-relevant files.
|
|
47
|
+
GRAPH_RELEVANT='^(src/.*\.py|tests/.*\.py|docs/.*\.md|ARCHITECTURE\.md|SPECIFICATION\.md|pyproject\.toml)$'
|
|
48
|
+
if ! git show --name-only --pretty=format: HEAD | grep -qE "$GRAPH_RELEVANT"; then
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
git submodule update --init graphify-out 2>/dev/null || true
|
|
53
|
+
|
|
54
|
+
export GRAPHIFY_VIZ_NODE_LIMIT="${GRAPHIFY_VIZ_NODE_LIMIT:-20000}"
|
|
55
|
+
if ! python3 -c "import numpy" 2>/dev/null; then
|
|
56
|
+
_LIBSTDCXX="$(gcc -print-file-name=libstdc++.so.6 2>/dev/null || true)"
|
|
57
|
+
if [ -n "$_LIBSTDCXX" ] && [ -f "$_LIBSTDCXX" ]; then
|
|
58
|
+
export LD_LIBRARY_PATH="$(dirname "$_LIBSTDCXX")${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
graphify install 2>/dev/null || true
|
|
63
|
+
graphify update . 2>/dev/null || true
|
|
64
|
+
graphify cluster-only . 2>/dev/null || true
|
|
65
|
+
graphify tree 2>/dev/null || true
|
|
66
|
+
[ -f graphify-out/graph.json ] && graphify export wiki 2>/dev/null || true
|
|
67
|
+
|
|
68
|
+
# Commit + push the refreshed artifacts inside the submodule.
|
|
69
|
+
if git -C graphify-out rev-parse --git-dir >/dev/null 2>&1 \
|
|
70
|
+
&& git -C graphify-out remote >/dev/null 2>&1; then
|
|
71
|
+
if ! git -C graphify-out diff --quiet; then
|
|
72
|
+
# -u stages modified tracked artifacts; -A also picks up newly
|
|
73
|
+
# generated wiki pages so the submodule stays clean.
|
|
74
|
+
git -C graphify-out add -u graph.json .graphify_labels.json \
|
|
75
|
+
.graphify_analysis.json .graphify_semantic_marker GRAPH_TREE.html \
|
|
76
|
+
GRAPH_REPORT.md graph.html wiki/ 2>/dev/null || true
|
|
77
|
+
git -C graphify-out add -A wiki/ 2>/dev/null || true
|
|
78
|
+
git -C graphify-out commit -m "chore: regenerate graph artifacts" >/dev/null 2>&1 || true
|
|
79
|
+
# Submodules sit on a detached HEAD, so a bare `git push` pushes
|
|
80
|
+
# nothing. Push the detached HEAD explicitly to the main branch.
|
|
81
|
+
git -C graphify-out push origin HEAD:main 2>/dev/null \
|
|
82
|
+
|| echo "graphify: submodule push skipped (no reachable remote)"
|
|
83
|
+
fi
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Fold the new submodule pointer into the just-created commit. Guarded so
|
|
87
|
+
# the post-commit fire from the amend itself returns immediately.
|
|
88
|
+
if ! git -C "$REPO_ROOT" diff --quiet HEAD -- graphify-out; then
|
|
89
|
+
git -C "$REPO_ROOT" add graphify-out
|
|
90
|
+
AOM_GRAPHIFY_POST_COMMIT=1 \
|
|
91
|
+
git -C "$REPO_ROOT" commit --amend --no-edit --no-verify >/dev/null 2>&1 \
|
|
92
|
+
|| true
|
|
93
|
+
fi
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# pre-push: run only the tests affected by what's being pushed.
|
|
3
|
+
#
|
|
4
|
+
# Two phases, deliberately asymmetric about the working tree:
|
|
5
|
+
#
|
|
6
|
+
# 1. SELECTION (~2-3s, tree briefly stashed): testmon --collect-only
|
|
7
|
+
# against the COMMITTED state. Everything — including untracked
|
|
8
|
+
# files — is stashed so concurrent agent sessions' WIP (red TDD
|
|
9
|
+
# tests, uncommitted fixes) can't leak into the selection. The
|
|
10
|
+
# stash is popped before any test runs.
|
|
11
|
+
#
|
|
12
|
+
# 2. EXECUTION (live tree, no stash): the selected node IDs run
|
|
13
|
+
# against the tree as-is, so a long test run never holds other
|
|
14
|
+
# sessions' files hostage. testmon stays enabled so .testmondata
|
|
15
|
+
# keeps draining; it may further deselect tests already proven
|
|
16
|
+
# green on byte-identical code (testmon always re-selects prior
|
|
17
|
+
# failures, so a deselect implies a prior pass).
|
|
18
|
+
#
|
|
19
|
+
# pytest intentionally does NOT live in .pre-commit-config.yaml's
|
|
20
|
+
# pre-push stage: the pre-commit framework stashes tracked-but-not-
|
|
21
|
+
# untracked files around the WHOLE hook run, which both races
|
|
22
|
+
# concurrent sessions and produces false failures (a session's
|
|
23
|
+
# untracked red test stays visible while its uncommitted fix is
|
|
24
|
+
# stashed away).
|
|
25
|
+
#
|
|
26
|
+
# --no-cov (not -p no:cov): keeps pytest-cov loaded so addopts'
|
|
27
|
+
# --cov-fail-under still parses, while stopping the coverage
|
|
28
|
+
# measurement that silently breaks testmon's DB updates.
|
|
29
|
+
set -euo pipefail
|
|
30
|
+
cd "$(git rev-parse --show-toplevel)"
|
|
31
|
+
|
|
32
|
+
PYTEST=(uv run --extra dev --extra integration pytest --testmon --no-cov -q)
|
|
33
|
+
|
|
34
|
+
# --- phase 1: selection against committed state -----------------------
|
|
35
|
+
stashed=0
|
|
36
|
+
restore_tree() {
|
|
37
|
+
if (( stashed )); then
|
|
38
|
+
stashed=0
|
|
39
|
+
# --index also restores staged-ness; plain pop is the fallback
|
|
40
|
+
# (content preserved, index state lost).
|
|
41
|
+
git stash pop --index --quiet 2>/dev/null \
|
|
42
|
+
|| git stash pop --quiet \
|
|
43
|
+
|| {
|
|
44
|
+
echo "pre-push: FAILED to restore stashed WIP — recover it" \
|
|
45
|
+
"from 'git stash list' (pre-push-test-selection)" >&2
|
|
46
|
+
return 1
|
|
47
|
+
}
|
|
48
|
+
fi
|
|
49
|
+
}
|
|
50
|
+
trap restore_tree EXIT
|
|
51
|
+
|
|
52
|
+
# Git exports GIT_DIR / GIT_INDEX_FILE etc. into hook processes; strip them
|
|
53
|
+
# now that we're in the worktree root so pytest fixtures spawning `git` in
|
|
54
|
+
# temp directories cannot accidentally target the real repository.
|
|
55
|
+
unset "${!GIT_@}"
|
|
56
|
+
|
|
57
|
+
if [[ -n "$(git status --porcelain)" ]]; then
|
|
58
|
+
git stash push --include-untracked --quiet -m "pre-push-test-selection"
|
|
59
|
+
stashed=1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
collect_rc=0
|
|
63
|
+
collected="$("${PYTEST[@]}" tests/ --collect-only -n0 2>&1)" || collect_rc=$?
|
|
64
|
+
restore_tree # pop as soon as selection is done; the trap stays as backstop
|
|
65
|
+
|
|
66
|
+
# exit 5 = "no tests collected" = nothing affected. Anything else
|
|
67
|
+
# non-zero is a real collection error in the committed state: block.
|
|
68
|
+
if (( collect_rc != 0 && collect_rc != 5 )); then
|
|
69
|
+
echo "$collected" >&2
|
|
70
|
+
echo "pre-push: test collection failed against the committed state" >&2
|
|
71
|
+
exit "$collect_rc"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
mapfile -t selected < <(grep -E '^tests/.*::' <<<"$collected" || true)
|
|
75
|
+
if (( ${#selected[@]} == 0 )); then
|
|
76
|
+
echo "pre-push: no tests affected by the pushed changes"
|
|
77
|
+
exit 0
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# --- phase 2: run the selection against the live tree -----------------
|
|
81
|
+
echo "pre-push: running ${#selected[@]} affected test(s) against the live tree"
|
|
82
|
+
run_rc=0
|
|
83
|
+
"${PYTEST[@]}" --tb=short "${selected[@]}" || run_rc=$?
|
|
84
|
+
# exit 5 here means testmon deselected everything we passed in — all of
|
|
85
|
+
# it already passed on identical code. That is a pass.
|
|
86
|
+
if (( run_rc == 5 )); then run_rc=0; fi
|
|
87
|
+
exit "$run_rc"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "uv"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
|
|
8
|
+
- package-ecosystem: "nix"
|
|
9
|
+
directory: "/"
|
|
10
|
+
schedule:
|
|
11
|
+
interval: "weekly"
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: "github-actions"
|
|
14
|
+
directory: "/"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: "weekly"
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# CI workflow for ansible-aom
|
|
2
|
+
# Runs lint (ruff) → type-check (mypy) → test (pytest with xdist)
|
|
3
|
+
# on push to main/master and on every pull_request (incl. stacked PRs
|
|
4
|
+
# whose base is another feature branch).
|
|
5
|
+
#
|
|
6
|
+
# Uses uv for Python dependency management (matching the project's
|
|
7
|
+
# existing tooling). Python 3.14 only — no matrix builds.
|
|
8
|
+
|
|
9
|
+
name: CI
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
UV_LOCKED: "true"
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [main, master]
|
|
17
|
+
pull_request:
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
ci:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v7
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
|
|
27
|
+
- name: Install uv
|
|
28
|
+
uses: astral-sh/setup-uv@v7
|
|
29
|
+
|
|
30
|
+
- name: Set up Python 3.14
|
|
31
|
+
uses: actions/setup-python@v7
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.14"
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: uv sync --all-extras --group release
|
|
37
|
+
|
|
38
|
+
- name: Check software version bump
|
|
39
|
+
run: uv run --no-sync python scripts/check_version_bump.py
|
|
40
|
+
|
|
41
|
+
- name: Lint (ruff format check)
|
|
42
|
+
run: uv run --no-sync ruff format --check src/
|
|
43
|
+
|
|
44
|
+
- name: Lint (ruff check)
|
|
45
|
+
run: uv run --no-sync ruff check src/
|
|
46
|
+
|
|
47
|
+
- name: Type-check (mypy)
|
|
48
|
+
run: uv run --no-sync mypy src/ansible_aom
|
|
49
|
+
|
|
50
|
+
- name: Test (pytest with xdist)
|
|
51
|
+
run: uv run --no-sync pytest tests/unit tests/compact tests/tui -q -n auto
|
|
52
|
+
|
|
53
|
+
- name: Build distributions
|
|
54
|
+
run: uv build --no-build-isolation
|
|
55
|
+
|
|
56
|
+
- name: Validate distributions
|
|
57
|
+
run: |
|
|
58
|
+
uv run --no-sync twine check dist/*
|
|
59
|
+
python -m venv /tmp/aom-ci-smoke
|
|
60
|
+
/tmp/aom-ci-smoke/bin/python -m pip install dist/*.whl
|
|
61
|
+
cd /tmp
|
|
62
|
+
/tmp/aom-ci-smoke/bin/aom --version
|
|
63
|
+
/tmp/aom-ci-smoke/bin/aom --help >/dev/null
|
|
64
|
+
/tmp/aom-ci-smoke/bin/python -c 'from pathlib import Path; import ansible_aom.ansible.runner as r; assert (Path(r.__file__).parent / "callback" / "aom_jsonl.py").is_file()'
|
|
65
|
+
|
|
66
|
+
nix:
|
|
67
|
+
runs-on: ubuntu-24.04
|
|
68
|
+
permissions:
|
|
69
|
+
contents: read
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v7
|
|
72
|
+
- uses: cachix/install-nix-action@v31
|
|
73
|
+
- name: Build Nix package
|
|
74
|
+
run: nix build .#default --no-update-lock-file
|
|
75
|
+
- name: Validate Nix package
|
|
76
|
+
run: |
|
|
77
|
+
./result/bin/aom --version
|
|
78
|
+
./result/bin/aom --help >/dev/null
|
|
79
|
+
- name: Evaluate development shell
|
|
80
|
+
run: nix eval --raw .#devShells.x86_64-linux.default.drvPath --no-update-lock-file
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
UV_LOCKED: "true"
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
tags:
|
|
11
|
+
- "v*"
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
check:
|
|
15
|
+
runs-on: ubuntu-24.04
|
|
16
|
+
outputs:
|
|
17
|
+
should_release: ${{ steps.evaluate.outputs.should_release }}
|
|
18
|
+
tag: ${{ steps.evaluate.outputs.tag }}
|
|
19
|
+
version: ${{ steps.evaluate.outputs.version }}
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v7
|
|
22
|
+
with:
|
|
23
|
+
fetch-depth: 0
|
|
24
|
+
- uses: actions/setup-python@v7
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.14"
|
|
27
|
+
- name: Evaluate release trigger
|
|
28
|
+
id: evaluate
|
|
29
|
+
run: python scripts/check_version_bump.py --check-release
|
|
30
|
+
|
|
31
|
+
build:
|
|
32
|
+
needs: check
|
|
33
|
+
if: needs.check.outputs.should_release == 'true'
|
|
34
|
+
runs-on: ubuntu-24.04
|
|
35
|
+
permissions:
|
|
36
|
+
contents: read
|
|
37
|
+
outputs:
|
|
38
|
+
tag: ${{ steps.validate.outputs.tag }}
|
|
39
|
+
version: ${{ steps.validate.outputs.version }}
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v7
|
|
42
|
+
- uses: actions/setup-python@v7
|
|
43
|
+
with:
|
|
44
|
+
python-version: "3.14"
|
|
45
|
+
- uses: astral-sh/setup-uv@v7
|
|
46
|
+
- name: Validate tag and project version
|
|
47
|
+
id: validate
|
|
48
|
+
env:
|
|
49
|
+
RELEASE_TAG: ${{ needs.check.outputs.tag || github.ref_name }}
|
|
50
|
+
run: |
|
|
51
|
+
python - <<'PY'
|
|
52
|
+
import os
|
|
53
|
+
import re
|
|
54
|
+
import tomllib
|
|
55
|
+
from pathlib import Path
|
|
56
|
+
|
|
57
|
+
tag = os.environ["RELEASE_TAG"]
|
|
58
|
+
if not re.fullmatch(r"v\d+\.\d+\.\d+", tag):
|
|
59
|
+
raise SystemExit(f"invalid release tag: {tag!r}; expected vX.Y.Z")
|
|
60
|
+
version = tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"]
|
|
61
|
+
if tag[1:] != version:
|
|
62
|
+
raise SystemExit(f"tag {tag} does not match project version {version}")
|
|
63
|
+
print(f"Releasing ansible-aom {version} ({tag})")
|
|
64
|
+
if "GITHUB_OUTPUT" in os.environ:
|
|
65
|
+
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as f:
|
|
66
|
+
f.write(f"tag={tag}\n")
|
|
67
|
+
f.write(f"version={version}\n")
|
|
68
|
+
PY
|
|
69
|
+
- name: Install locked runtime and release tools
|
|
70
|
+
run: uv sync --no-default-groups --group release --no-install-project
|
|
71
|
+
- name: Build Python distributions
|
|
72
|
+
run: uv build --no-build-isolation
|
|
73
|
+
- name: Validate Python distributions
|
|
74
|
+
run: |
|
|
75
|
+
uv run --no-sync twine check dist/*
|
|
76
|
+
python -m venv /tmp/aom-wheel-smoke
|
|
77
|
+
/tmp/aom-wheel-smoke/bin/python -m pip install dist/*.whl
|
|
78
|
+
cd /tmp
|
|
79
|
+
/tmp/aom-wheel-smoke/bin/aom --version
|
|
80
|
+
/tmp/aom-wheel-smoke/bin/aom --help >/dev/null
|
|
81
|
+
/tmp/aom-wheel-smoke/bin/python -c 'from pathlib import Path; import ansible_aom.ansible.runner as r; assert (Path(r.__file__).parent / "callback" / "aom_jsonl.py").is_file()'
|
|
82
|
+
- name: Build Linux standalone bundle
|
|
83
|
+
run: |
|
|
84
|
+
uv pip install --no-deps dist/*.whl
|
|
85
|
+
uv run --no-sync pyinstaller --clean --noconfirm --distpath build-dist --workpath build-work packaging/aom.spec
|
|
86
|
+
test -x build-dist/aom/aom
|
|
87
|
+
tar -C build-dist -czf dist/aom-linux-x86_64.tar.gz aom
|
|
88
|
+
- name: Validate standalone bundle
|
|
89
|
+
run: |
|
|
90
|
+
test -f build-dist/aom/aom
|
|
91
|
+
test -f build-dist/aom/_internal/ansible_aom/ansible/callback/aom_jsonl.py
|
|
92
|
+
test -f build-dist/aom/_internal/ansible_aom/callbacks/aom_connection.py
|
|
93
|
+
test -f build-dist/aom/_internal/ansible_aom/core/default_config.yaml
|
|
94
|
+
build-dist/aom/aom --version
|
|
95
|
+
build-dist/aom/aom --help >/dev/null
|
|
96
|
+
- uses: actions/upload-artifact@v7
|
|
97
|
+
with:
|
|
98
|
+
name: release-artifacts
|
|
99
|
+
path: dist/
|
|
100
|
+
if-no-files-found: error
|
|
101
|
+
|
|
102
|
+
github-release:
|
|
103
|
+
needs: [check, build]
|
|
104
|
+
runs-on: ubuntu-24.04
|
|
105
|
+
permissions:
|
|
106
|
+
contents: write
|
|
107
|
+
steps:
|
|
108
|
+
- uses: actions/download-artifact@v8
|
|
109
|
+
with:
|
|
110
|
+
name: release-artifacts
|
|
111
|
+
path: dist
|
|
112
|
+
- name: Create GitHub Release
|
|
113
|
+
env:
|
|
114
|
+
GH_TOKEN: ${{ github.token }}
|
|
115
|
+
GH_REPO: ${{ github.repository }}
|
|
116
|
+
run: gh release create "${{ needs.build.outputs.tag || needs.check.outputs.tag }}" dist/* --generate-notes --target "${{ github.sha }}"
|
|
117
|
+
|
|
118
|
+
pypi:
|
|
119
|
+
needs: [check, build]
|
|
120
|
+
runs-on: ubuntu-24.04
|
|
121
|
+
permissions:
|
|
122
|
+
id-token: write
|
|
123
|
+
environment:
|
|
124
|
+
name: pypi
|
|
125
|
+
url: https://pypi.org/p/ansible-aom
|
|
126
|
+
steps:
|
|
127
|
+
- uses: actions/download-artifact@v8
|
|
128
|
+
with:
|
|
129
|
+
name: release-artifacts
|
|
130
|
+
path: dist
|
|
131
|
+
- name: Keep only Python distributions
|
|
132
|
+
run: rm dist/aom-linux-x86_64.tar.gz
|
|
133
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
134
|
+
with:
|
|
135
|
+
packages-dir: dist
|