Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/compatibility-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,34 @@ name: Compatibility Matrix

on:
pull_request:
paths-ignore:
- "**/*.md"
- "**/*.txt"
- "**/*.rst"
- "**/*.png"
- "**/*.jpg"
- "**/*.jpeg"
- "**/*.gif"
- "**/*.svg"
- "**/*.webp"
- "**/*.ico"
- "**/*.pdf"
- "LICENSE*"
push:
branches: [main]
paths-ignore:
- "**/*.md"
- "**/*.txt"
- "**/*.rst"
- "**/*.png"
- "**/*.jpg"
- "**/*.jpeg"
- "**/*.gif"
- "**/*.svg"
- "**/*.webp"
- "**/*.ico"
- "**/*.pdf"
- "LICENSE*"
workflow_dispatch:

permissions:
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/dependency-submission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ name: Repository Dependency Snapshot
on:
push:
branches: [main]
paths-ignore:
- "**/*.md"
- "**/*.txt"
- "**/*.rst"
- "**/*.png"
- "**/*.jpg"
- "**/*.jpeg"
- "**/*.gif"
- "**/*.svg"
- "**/*.webp"
- "**/*.ico"
- "**/*.pdf"
- "LICENSE*"
workflow_dispatch:

permissions:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/devflow-contract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ on:
paths:
- ".github/workflows/devflow-contract.yml"
- "platform/configs/devflow/**"
- "platform/docs/DEVFLOW.md"
- "platform/workers/acpx/**"
- "src/clawops/devflow.py"
- "src/clawops/devflow_*.py"
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/fresh-host-acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@ name: Fresh Host Acceptance

on:
pull_request:
paths:
- ".github/workflows/fresh-host-acceptance.yml"
- ".github/workflows/fresh-host-cache-warm.yml"
- ".github/workflows/fresh-host-core.yml"
- "platform/compose/**"
- "platform/configs/**"
- "platform/plugins/**"
- "platform/workers/**"
- "platform/workspace/**"
- "scripts/**"
- "src/**"
- "tests/scripts/**"
- "tests/utils/helpers/**"
- "pyproject.toml"
- "uv.lock"
workflow_dispatch:
inputs:
macos_runtime_provider:
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/harness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@ name: Policy Harness Smoke Tests

on:
pull_request:
paths-ignore:
- "**/*.md"
- "**/*.txt"
- "**/*.rst"
- "**/*.png"
- "**/*.jpg"
- "**/*.jpeg"
- "**/*.gif"
- "**/*.svg"
- "**/*.webp"
- "**/*.ico"
- "**/*.pdf"
- "LICENSE*"
workflow_dispatch:

permissions:
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/memory-plugin-verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,34 @@ name: Memory Plugin Integration Checks

on:
pull_request:
paths-ignore:
- "**/*.md"
- "**/*.txt"
- "**/*.rst"
- "**/*.png"
- "**/*.jpg"
- "**/*.jpeg"
- "**/*.gif"
- "**/*.svg"
- "**/*.webp"
- "**/*.ico"
- "**/*.pdf"
- "LICENSE*"
push:
branches: [main]
paths-ignore:
- "**/*.md"
- "**/*.txt"
- "**/*.rst"
- "**/*.png"
- "**/*.jpg"
- "**/*.jpeg"
- "**/*.gif"
- "**/*.svg"
- "**/*.webp"
- "**/*.ico"
- "**/*.pdf"
- "LICENSE*"
workflow_dispatch:

permissions:
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,34 @@ name: Repository Security Analysis

on:
pull_request:
paths-ignore:
- "**/*.md"
- "**/*.txt"
- "**/*.rst"
- "**/*.png"
- "**/*.jpg"
- "**/*.jpeg"
- "**/*.gif"
- "**/*.svg"
- "**/*.webp"
- "**/*.ico"
- "**/*.pdf"
- "LICENSE*"
push:
branches: [main]
paths-ignore:
- "**/*.md"
- "**/*.txt"
- "**/*.rst"
- "**/*.png"
- "**/*.jpg"
- "**/*.jpeg"
- "**/*.gif"
- "**/*.svg"
- "**/*.webp"
- "**/*.ico"
- "**/*.pdf"
- "LICENSE*"

permissions:
actions: read
Expand Down
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ repos:
entry: uv run pyright
language: system
pass_filenames: false
types_or: [python, pyi]
- id: mypy
name: mypy
entry: uv run mypy
language: system
pass_filenames: false
types_or: [python, pyi]
- id: shellcheck
name: shellcheck
entry: shellcheck
Expand Down
12 changes: 12 additions & 0 deletions tests/suites/contracts/repo/test_ci_quality_gate_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from __future__ import annotations

import yaml

from clawops.supply_chain import list_workflow_action_pins
from tests.utils.helpers.repo import REPO_ROOT

Expand Down Expand Up @@ -49,6 +51,16 @@ def test_pre_commit_shellcheck_uses_system_binary() -> None:
assert "language: system" in pre_commit_config


def test_pre_commit_python_type_hooks_only_run_for_python_changes() -> None:
payload = yaml.safe_load((REPO_ROOT / ".pre-commit-config.yaml").read_text(encoding="utf-8"))
local_repo = next(repo for repo in payload["repos"] if repo["repo"] == "local")
hooks = {hook["id"]: hook for hook in local_repo["hooks"]}

for hook_id in ("pyright", "mypy"):
assert hooks[hook_id]["pass_filenames"] is False
assert hooks[hook_id]["types_or"] == ["python", "pyi"]


def test_security_workflow_verifies_downloaded_tool_archives() -> None:
workflow = _workflow_text("security.yml")

Expand Down
56 changes: 55 additions & 1 deletion tests/suites/contracts/repo/test_ci_workflow_surfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@
r"(?P<prefix>(?:^|[\s;])(?:(?:uv\s+run\s+)?python3?\s+)?)"
r"(?P<script>\./tests/scripts/[A-Za-z0-9_./-]+\.py)\b"
)
_NON_IMPACTFUL_PATH_FILTER_MARKERS = (
'"**/*.md"',
'"**/*.txt"',
'"**/*.rst"',
'"**/*.png"',
'"**/*.jpg"',
'"**/*.jpeg"',
'"**/*.gif"',
'"**/*.svg"',
'"**/*.webp"',
'"**/*.ico"',
'"**/*.pdf"',
'"LICENSE*"',
)


def _workflow_text(workflow_name: str) -> str:
Expand Down Expand Up @@ -87,12 +101,36 @@ def test_fresh_host_acceptance_workflow_routes_to_reusable_core() -> None:
"""The trigger workflow should delegate execution to the reusable core workflow."""
text = _workflow_text("fresh-host-acceptance.yml")

assert "pull_request:" in text
assert "pull_request:\n paths:" in text
assert "workflow_dispatch:" in text
assert "push:" not in text
assert "uses: ./.github/workflows/fresh-host-core.yml" in text


def test_fresh_host_acceptance_workflow_limits_pull_request_paths_to_runtime_surfaces() -> None:
"""Fresh-host acceptance should only trigger for runtime-affecting pull-request changes."""
text = _workflow_text("fresh-host-acceptance.yml")

for marker in (
'".github/workflows/fresh-host-acceptance.yml"',
'".github/workflows/fresh-host-cache-warm.yml"',
'".github/workflows/fresh-host-core.yml"',
'"platform/compose/**"',
'"platform/configs/**"',
'"platform/plugins/**"',
'"platform/workers/**"',
'"platform/workspace/**"',
'"scripts/**"',
'"src/**"',
'"tests/scripts/**"',
'"tests/utils/helpers/**"',
'"pyproject.toml"',
'"uv.lock"',
):
assert marker in text
assert "platform/docs/**" not in text


def test_fresh_host_core_workflow_uses_semantic_test_scripts() -> None:
"""Fresh-host core should delegate orchestration to dedicated scripts."""
text = _workflow_text("fresh-host-core.yml")
Expand Down Expand Up @@ -230,12 +268,28 @@ def test_remaining_workflow_logic_routes_through_semantic_scripts() -> None:
assert "./tests/scripts/release_workflow.py publish-github-release" in release


def test_selected_workflows_ignore_docs_and_static_only_changes() -> None:
"""General CI pull-request and push lanes should skip docs-only and static-only changes."""
for workflow_name in (
"compatibility-matrix.yml",
"dependency-submission.yml",
"harness.yml",
"memory-plugin-verification.yml",
"security.yml",
):
text = _workflow_text(workflow_name)
assert "paths-ignore:" in text, workflow_name
for marker in _NON_IMPACTFUL_PATH_FILTER_MARKERS:
assert marker in text, workflow_name


def test_devflow_contract_workflow_surfaces_public_devflow_lane() -> None:
text = _workflow_text("devflow-contract.yml")

assert "uv sync --locked" in text
assert "uv run python -m compileall -q src tests" in text
assert 'uv run clawops devflow plan --project-root . --goal "contract smoke"' in text
assert '"platform/docs/DEVFLOW.md"' not in text


def test_security_harness_tracks_the_context_provider_namespace() -> None:
Expand Down
Loading